ActivityManagerService.java revision 7767eac3232ba2fb9828766813cdb481d6a97584
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20
21import com.android.internal.R;
22import com.android.internal.os.BatteryStatsImpl;
23import com.android.internal.os.ProcessStats;
24import com.android.server.AttributeCache;
25import com.android.server.IntentResolver;
26import com.android.server.ProcessMap;
27import com.android.server.SystemServer;
28import com.android.server.Watchdog;
29import com.android.server.am.ActivityStack.ActivityState;
30import com.android.server.wm.WindowManagerService;
31
32import dalvik.system.Zygote;
33
34import android.app.Activity;
35import android.app.ActivityManager;
36import android.app.ActivityManagerNative;
37import android.app.ActivityOptions;
38import android.app.ActivityThread;
39import android.app.AlertDialog;
40import android.app.AppGlobals;
41import android.app.ApplicationErrorReport;
42import android.app.Dialog;
43import android.app.IActivityController;
44import android.app.IApplicationThread;
45import android.app.IInstrumentationWatcher;
46import android.app.INotificationManager;
47import android.app.IProcessObserver;
48import android.app.IServiceConnection;
49import android.app.IThumbnailReceiver;
50import android.app.Instrumentation;
51import android.app.Notification;
52import android.app.NotificationManager;
53import android.app.PendingIntent;
54import android.app.backup.IBackupManager;
55import android.content.ActivityNotFoundException;
56import android.content.BroadcastReceiver;
57import android.content.ClipData;
58import android.content.ComponentCallbacks2;
59import android.content.ComponentName;
60import android.content.ContentProvider;
61import android.content.ContentResolver;
62import android.content.Context;
63import android.content.DialogInterface;
64import android.content.IContentProvider;
65import android.content.IIntentReceiver;
66import android.content.IIntentSender;
67import android.content.Intent;
68import android.content.IntentFilter;
69import android.content.IntentSender;
70import android.content.pm.ActivityInfo;
71import android.content.pm.ApplicationInfo;
72import android.content.pm.ConfigurationInfo;
73import android.content.pm.IPackageDataObserver;
74import android.content.pm.IPackageManager;
75import android.content.pm.InstrumentationInfo;
76import android.content.pm.PackageInfo;
77import android.content.pm.PackageManager;
78import android.content.pm.UserInfo;
79import android.content.pm.PackageManager.NameNotFoundException;
80import android.content.pm.PathPermission;
81import android.content.pm.ProviderInfo;
82import android.content.pm.ResolveInfo;
83import android.content.pm.ServiceInfo;
84import android.content.res.CompatibilityInfo;
85import android.content.res.Configuration;
86import android.graphics.Bitmap;
87import android.net.Proxy;
88import android.net.ProxyProperties;
89import android.net.Uri;
90import android.os.Binder;
91import android.os.Build;
92import android.os.Bundle;
93import android.os.Debug;
94import android.os.DropBoxManager;
95import android.os.Environment;
96import android.os.FileObserver;
97import android.os.FileUtils;
98import android.os.Handler;
99import android.os.IBinder;
100import android.os.IPermissionController;
101import android.os.Looper;
102import android.os.Message;
103import android.os.Parcel;
104import android.os.ParcelFileDescriptor;
105import android.os.Process;
106import android.os.RemoteCallbackList;
107import android.os.RemoteException;
108import android.os.SELinux;
109import android.os.ServiceManager;
110import android.os.StrictMode;
111import android.os.SystemClock;
112import android.os.SystemProperties;
113import android.os.UserHandle;
114import android.os.UserManager;
115import android.provider.Settings;
116import android.text.format.Time;
117import android.util.EventLog;
118import android.util.Log;
119import android.util.Pair;
120import android.util.PrintWriterPrinter;
121import android.util.Slog;
122import android.util.SparseArray;
123import android.util.SparseIntArray;
124import android.util.TimeUtils;
125import android.view.Gravity;
126import android.view.LayoutInflater;
127import android.view.View;
128import android.view.WindowManager;
129import android.view.WindowManagerPolicy;
130
131import java.io.BufferedInputStream;
132import java.io.BufferedOutputStream;
133import java.io.BufferedReader;
134import java.io.DataInputStream;
135import java.io.DataOutputStream;
136import java.io.File;
137import java.io.FileDescriptor;
138import java.io.FileInputStream;
139import java.io.FileNotFoundException;
140import java.io.FileOutputStream;
141import java.io.IOException;
142import java.io.InputStreamReader;
143import java.io.PrintWriter;
144import java.io.StringWriter;
145import java.lang.ref.WeakReference;
146import java.util.ArrayList;
147import java.util.Collections;
148import java.util.Comparator;
149import java.util.HashMap;
150import java.util.HashSet;
151import java.util.Iterator;
152import java.util.List;
153import java.util.Locale;
154import java.util.Map;
155import java.util.Map.Entry;
156import java.util.Set;
157import java.util.concurrent.atomic.AtomicBoolean;
158import java.util.concurrent.atomic.AtomicLong;
159
160public final class ActivityManagerService extends ActivityManagerNative
161        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
162    private static final String USER_DATA_DIR = "/data/user/";
163    static final String TAG = "ActivityManager";
164    static final String TAG_MU = "ActivityManagerServiceMU";
165    static final boolean DEBUG = false;
166    static final boolean localLOGV = DEBUG;
167    static final boolean DEBUG_SWITCH = localLOGV || false;
168    static final boolean DEBUG_TASKS = localLOGV || false;
169    static final boolean DEBUG_PAUSE = localLOGV || false;
170    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
171    static final boolean DEBUG_TRANSITION = localLOGV || false;
172    static final boolean DEBUG_BROADCAST = localLOGV || false;
173    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
174    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
175    static final boolean DEBUG_SERVICE = localLOGV || false;
176    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
177    static final boolean DEBUG_VISBILITY = localLOGV || false;
178    static final boolean DEBUG_PROCESSES = localLOGV || false;
179    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
180    static final boolean DEBUG_PROVIDER = localLOGV || false;
181    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
182    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
183    static final boolean DEBUG_RESULTS = localLOGV || false;
184    static final boolean DEBUG_BACKUP = localLOGV || false;
185    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
186    static final boolean DEBUG_POWER = localLOGV || false;
187    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
188    static final boolean DEBUG_MU = localLOGV || false;
189    static final boolean VALIDATE_TOKENS = false;
190    static final boolean SHOW_ACTIVITY_START_TIME = true;
191
192    // Control over CPU and battery monitoring.
193    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
194    static final boolean MONITOR_CPU_USAGE = true;
195    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
196    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
197    static final boolean MONITOR_THREAD_CPU_USAGE = false;
198
199    // The flags that are set for all calls we make to the package manager.
200    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
201
202    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
203
204    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
205
206    // Maximum number of recent tasks that we can remember.
207    static final int MAX_RECENT_TASKS = 20;
208
209    // Amount of time after a call to stopAppSwitches() during which we will
210    // prevent further untrusted switches from happening.
211    static final long APP_SWITCH_DELAY_TIME = 5*1000;
212
213    // How long we wait for a launched process to attach to the activity manager
214    // before we decide it's never going to come up for real.
215    static final int PROC_START_TIMEOUT = 10*1000;
216
217    // How long we wait for a launched process to attach to the activity manager
218    // before we decide it's never going to come up for real, when the process was
219    // started with a wrapper for instrumentation (such as Valgrind) because it
220    // could take much longer than usual.
221    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
222
223    // How long to wait after going idle before forcing apps to GC.
224    static final int GC_TIMEOUT = 5*1000;
225
226    // The minimum amount of time between successive GC requests for a process.
227    static final int GC_MIN_INTERVAL = 60*1000;
228
229    // The rate at which we check for apps using excessive power -- 15 mins.
230    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
231
232    // The minimum sample duration we will allow before deciding we have
233    // enough data on wake locks to start killing things.
234    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
235
236    // The minimum sample duration we will allow before deciding we have
237    // enough data on CPU usage to start killing things.
238    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
239
240    // How long we allow a receiver to run before giving up on it.
241    static final int BROADCAST_FG_TIMEOUT = 10*1000;
242    static final int BROADCAST_BG_TIMEOUT = 60*1000;
243
244    // How long we wait until we timeout on key dispatching.
245    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
246
247    // How long we wait until we timeout on key dispatching during instrumentation.
248    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
249
250    static final int MY_PID = Process.myPid();
251
252    static final String[] EMPTY_STRING_ARRAY = new String[0];
253
254    public ActivityStack mMainStack;
255
256    private final boolean mHeadless;
257
258    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
259    // default actuion automatically.  Important for devices without direct input
260    // devices.
261    private boolean mShowDialogs = true;
262
263    /**
264     * Description of a request to start a new activity, which has been held
265     * due to app switches being disabled.
266     */
267    static class PendingActivityLaunch {
268        ActivityRecord r;
269        ActivityRecord sourceRecord;
270        int startFlags;
271    }
272
273    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
274            = new ArrayList<PendingActivityLaunch>();
275
276
277    BroadcastQueue mFgBroadcastQueue;
278    BroadcastQueue mBgBroadcastQueue;
279    // Convenient for easy iteration over the queues. Foreground is first
280    // so that dispatch of foreground broadcasts gets precedence.
281    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
282
283    BroadcastQueue broadcastQueueForIntent(Intent intent) {
284        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
285        if (DEBUG_BACKGROUND_BROADCAST) {
286            Slog.i(TAG, "Broadcast intent " + intent + " on "
287                    + (isFg ? "foreground" : "background")
288                    + " queue");
289        }
290        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
291    }
292
293    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
294        for (BroadcastQueue queue : mBroadcastQueues) {
295            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
296            if (r != null) {
297                return r;
298            }
299        }
300        return null;
301    }
302
303    /**
304     * Activity we have told the window manager to have key focus.
305     */
306    ActivityRecord mFocusedActivity = null;
307    /**
308     * List of intents that were used to start the most recent tasks.
309     */
310    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
311
312    /**
313     * Process management.
314     */
315    final ProcessList mProcessList = new ProcessList();
316
317    /**
318     * All of the applications we currently have running organized by name.
319     * The keys are strings of the application package name (as
320     * returned by the package manager), and the keys are ApplicationRecord
321     * objects.
322     */
323    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
324
325    /**
326     * The currently running isolated processes.
327     */
328    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
329
330    /**
331     * Counter for assigning isolated process uids, to avoid frequently reusing the
332     * same ones.
333     */
334    int mNextIsolatedProcessUid = 0;
335
336    /**
337     * The currently running heavy-weight process, if any.
338     */
339    ProcessRecord mHeavyWeightProcess = null;
340
341    /**
342     * The last time that various processes have crashed.
343     */
344    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
345
346    /**
347     * Set of applications that we consider to be bad, and will reject
348     * incoming broadcasts from (which the user has no control over).
349     * Processes are added to this set when they have crashed twice within
350     * a minimum amount of time; they are removed from it when they are
351     * later restarted (hopefully due to some user action).  The value is the
352     * time it was added to the list.
353     */
354    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
355
356    /**
357     * All of the processes we currently have running organized by pid.
358     * The keys are the pid running the application.
359     *
360     * <p>NOTE: This object is protected by its own lock, NOT the global
361     * activity manager lock!
362     */
363    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
364
365    /**
366     * All of the processes that have been forced to be foreground.  The key
367     * is the pid of the caller who requested it (we hold a death
368     * link on it).
369     */
370    abstract class ForegroundToken implements IBinder.DeathRecipient {
371        int pid;
372        IBinder token;
373    }
374    final SparseArray<ForegroundToken> mForegroundProcesses
375            = new SparseArray<ForegroundToken>();
376
377    /**
378     * List of records for processes that someone had tried to start before the
379     * system was ready.  We don't start them at that point, but ensure they
380     * are started by the time booting is complete.
381     */
382    final ArrayList<ProcessRecord> mProcessesOnHold
383            = new ArrayList<ProcessRecord>();
384
385    /**
386     * List of persistent applications that are in the process
387     * of being started.
388     */
389    final ArrayList<ProcessRecord> mPersistentStartingProcesses
390            = new ArrayList<ProcessRecord>();
391
392    /**
393     * Processes that are being forcibly torn down.
394     */
395    final ArrayList<ProcessRecord> mRemovedProcesses
396            = new ArrayList<ProcessRecord>();
397
398    /**
399     * List of running applications, sorted by recent usage.
400     * The first entry in the list is the least recently used.
401     * It contains ApplicationRecord objects.  This list does NOT include
402     * any persistent application records (since we never want to exit them).
403     */
404    final ArrayList<ProcessRecord> mLruProcesses
405            = new ArrayList<ProcessRecord>();
406
407    /**
408     * List of processes that should gc as soon as things are idle.
409     */
410    final ArrayList<ProcessRecord> mProcessesToGc
411            = new ArrayList<ProcessRecord>();
412
413    /**
414     * This is the process holding what we currently consider to be
415     * the "home" activity.
416     */
417    ProcessRecord mHomeProcess;
418
419    /**
420     * This is the process holding the activity the user last visited that
421     * is in a different process from the one they are currently in.
422     */
423    ProcessRecord mPreviousProcess;
424
425    /**
426     * The time at which the previous process was last visible.
427     */
428    long mPreviousProcessVisibleTime;
429
430    /**
431     * Packages that the user has asked to have run in screen size
432     * compatibility mode instead of filling the screen.
433     */
434    final CompatModePackages mCompatModePackages;
435
436    /**
437     * Set of PendingResultRecord objects that are currently active.
438     */
439    final HashSet mPendingResultRecords = new HashSet();
440
441    /**
442     * Set of IntentSenderRecord objects that are currently active.
443     */
444    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
445            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
446
447    /**
448     * Fingerprints (hashCode()) of stack traces that we've
449     * already logged DropBox entries for.  Guarded by itself.  If
450     * something (rogue user app) forces this over
451     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
452     */
453    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
454    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
455
456    /**
457     * Strict Mode background batched logging state.
458     *
459     * The string buffer is guarded by itself, and its lock is also
460     * used to determine if another batched write is already
461     * in-flight.
462     */
463    private final StringBuilder mStrictModeBuffer = new StringBuilder();
464
465    /**
466     * Keeps track of all IIntentReceivers that have been registered for
467     * broadcasts.  Hash keys are the receiver IBinder, hash value is
468     * a ReceiverList.
469     */
470    final HashMap mRegisteredReceivers = new HashMap();
471
472    /**
473     * Resolver for broadcast intents to registered receivers.
474     * Holds BroadcastFilter (subclass of IntentFilter).
475     */
476    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
477            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
478        @Override
479        protected boolean allowFilterResult(
480                BroadcastFilter filter, List<BroadcastFilter> dest) {
481            IBinder target = filter.receiverList.receiver.asBinder();
482            for (int i=dest.size()-1; i>=0; i--) {
483                if (dest.get(i).receiverList.receiver.asBinder() == target) {
484                    return false;
485                }
486            }
487            return true;
488        }
489
490        @Override
491        protected BroadcastFilter[] newArray(int size) {
492            return new BroadcastFilter[size];
493        }
494
495        @Override
496        protected String packageForFilter(BroadcastFilter filter) {
497            return filter.packageName;
498        }
499    };
500
501    /**
502     * State of all active sticky broadcasts.  Keys are the action of the
503     * sticky Intent, values are an ArrayList of all broadcasted intents with
504     * that action (which should usually be one).
505     */
506    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
507            new HashMap<String, ArrayList<Intent>>();
508
509    final ActiveServices mServices;
510
511    /**
512     * Backup/restore process management
513     */
514    String mBackupAppName = null;
515    BackupRecord mBackupTarget = null;
516
517    /**
518     * List of PendingThumbnailsRecord objects of clients who are still
519     * waiting to receive all of the thumbnails for a task.
520     */
521    final ArrayList mPendingThumbnails = new ArrayList();
522
523    /**
524     * List of HistoryRecord objects that have been finished and must
525     * still report back to a pending thumbnail receiver.
526     */
527    final ArrayList mCancelledThumbnails = new ArrayList();
528
529    final ProviderMap mProviderMap = new ProviderMap();
530
531    /**
532     * List of content providers who have clients waiting for them.  The
533     * application is currently being launched and the provider will be
534     * removed from this list once it is published.
535     */
536    final ArrayList<ContentProviderRecord> mLaunchingProviders
537            = new ArrayList<ContentProviderRecord>();
538
539    /**
540     * Global set of specific Uri permissions that have been granted.
541     */
542    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
543            = new SparseArray<HashMap<Uri, UriPermission>>();
544
545    CoreSettingsObserver mCoreSettingsObserver;
546
547    /**
548     * Thread-local storage used to carry caller permissions over through
549     * indirect content-provider access.
550     * @see #ActivityManagerService.openContentUri()
551     */
552    private class Identity {
553        public int pid;
554        public int uid;
555
556        Identity(int _pid, int _uid) {
557            pid = _pid;
558            uid = _uid;
559        }
560    }
561
562    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
563
564    /**
565     * All information we have collected about the runtime performance of
566     * any user id that can impact battery performance.
567     */
568    final BatteryStatsService mBatteryStatsService;
569
570    /**
571     * information about component usage
572     */
573    final UsageStatsService mUsageStatsService;
574
575    /**
576     * Current configuration information.  HistoryRecord objects are given
577     * a reference to this object to indicate which configuration they are
578     * currently running in, so this object must be kept immutable.
579     */
580    Configuration mConfiguration = new Configuration();
581
582    /**
583     * Current sequencing integer of the configuration, for skipping old
584     * configurations.
585     */
586    int mConfigurationSeq = 0;
587
588    /**
589     * Hardware-reported OpenGLES version.
590     */
591    final int GL_ES_VERSION;
592
593    /**
594     * List of initialization arguments to pass to all processes when binding applications to them.
595     * For example, references to the commonly used services.
596     */
597    HashMap<String, IBinder> mAppBindArgs;
598
599    /**
600     * Temporary to avoid allocations.  Protected by main lock.
601     */
602    final StringBuilder mStringBuilder = new StringBuilder(256);
603
604    /**
605     * Used to control how we initialize the service.
606     */
607    boolean mStartRunning = false;
608    ComponentName mTopComponent;
609    String mTopAction;
610    String mTopData;
611    boolean mProcessesReady = false;
612    boolean mSystemReady = false;
613    boolean mBooting = false;
614    boolean mWaitingUpdate = false;
615    boolean mDidUpdate = false;
616    boolean mOnBattery = false;
617    boolean mLaunchWarningShown = false;
618
619    Context mContext;
620
621    int mFactoryTest;
622
623    boolean mCheckedForSetup;
624
625    /**
626     * The time at which we will allow normal application switches again,
627     * after a call to {@link #stopAppSwitches()}.
628     */
629    long mAppSwitchesAllowedTime;
630
631    /**
632     * This is set to true after the first switch after mAppSwitchesAllowedTime
633     * is set; any switches after that will clear the time.
634     */
635    boolean mDidAppSwitch;
636
637    /**
638     * Last time (in realtime) at which we checked for power usage.
639     */
640    long mLastPowerCheckRealtime;
641
642    /**
643     * Last time (in uptime) at which we checked for power usage.
644     */
645    long mLastPowerCheckUptime;
646
647    /**
648     * Set while we are wanting to sleep, to prevent any
649     * activities from being started/resumed.
650     */
651    boolean mSleeping = false;
652
653    /**
654     * State of external calls telling us if the device is asleep.
655     */
656    boolean mWentToSleep = false;
657
658    /**
659     * State of external call telling us if the lock screen is shown.
660     */
661    boolean mLockScreenShown = false;
662
663    /**
664     * Set if we are shutting down the system, similar to sleeping.
665     */
666    boolean mShuttingDown = false;
667
668    /**
669     * Task identifier that activities are currently being started
670     * in.  Incremented each time a new task is created.
671     * todo: Replace this with a TokenSpace class that generates non-repeating
672     * integers that won't wrap.
673     */
674    int mCurTask = 1;
675
676    /**
677     * Current sequence id for oom_adj computation traversal.
678     */
679    int mAdjSeq = 0;
680
681    /**
682     * Current sequence id for process LRU updating.
683     */
684    int mLruSeq = 0;
685
686    /**
687     * Keep track of the non-hidden/empty process we last found, to help
688     * determine how to distribute hidden/empty processes next time.
689     */
690    int mNumNonHiddenProcs = 0;
691
692    /**
693     * Keep track of the number of hidden procs, to balance oom adj
694     * distribution between those and empty procs.
695     */
696    int mNumHiddenProcs = 0;
697
698    /**
699     * Keep track of the number of service processes we last found, to
700     * determine on the next iteration which should be B services.
701     */
702    int mNumServiceProcs = 0;
703    int mNewNumServiceProcs = 0;
704
705    /**
706     * System monitoring: number of processes that died since the last
707     * N procs were started.
708     */
709    int[] mProcDeaths = new int[20];
710
711    /**
712     * This is set if we had to do a delayed dexopt of an app before launching
713     * it, to increasing the ANR timeouts in that case.
714     */
715    boolean mDidDexOpt;
716
717    String mDebugApp = null;
718    boolean mWaitForDebugger = false;
719    boolean mDebugTransient = false;
720    String mOrigDebugApp = null;
721    boolean mOrigWaitForDebugger = false;
722    boolean mAlwaysFinishActivities = false;
723    IActivityController mController = null;
724    String mProfileApp = null;
725    ProcessRecord mProfileProc = null;
726    String mProfileFile;
727    ParcelFileDescriptor mProfileFd;
728    int mProfileType = 0;
729    boolean mAutoStopProfiler = false;
730    String mOpenGlTraceApp = null;
731
732    static class ProcessChangeItem {
733        static final int CHANGE_ACTIVITIES = 1<<0;
734        static final int CHANGE_IMPORTANCE= 1<<1;
735        int changes;
736        int uid;
737        int pid;
738        int importance;
739        boolean foregroundActivities;
740    }
741
742    final RemoteCallbackList<IProcessObserver> mProcessObservers
743            = new RemoteCallbackList<IProcessObserver>();
744    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
745
746    final ArrayList<ProcessChangeItem> mPendingProcessChanges
747            = new ArrayList<ProcessChangeItem>();
748    final ArrayList<ProcessChangeItem> mAvailProcessChanges
749            = new ArrayList<ProcessChangeItem>();
750
751    /**
752     * Callback of last caller to {@link #requestPss}.
753     */
754    Runnable mRequestPssCallback;
755
756    /**
757     * Remaining processes for which we are waiting results from the last
758     * call to {@link #requestPss}.
759     */
760    final ArrayList<ProcessRecord> mRequestPssList
761            = new ArrayList<ProcessRecord>();
762
763    /**
764     * Runtime statistics collection thread.  This object's lock is used to
765     * protect all related state.
766     */
767    final Thread mProcessStatsThread;
768
769    /**
770     * Used to collect process stats when showing not responding dialog.
771     * Protected by mProcessStatsThread.
772     */
773    final ProcessStats mProcessStats = new ProcessStats(
774            MONITOR_THREAD_CPU_USAGE);
775    final AtomicLong mLastCpuTime = new AtomicLong(0);
776    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
777
778    long mLastWriteTime = 0;
779
780    /**
781     * Set to true after the system has finished booting.
782     */
783    boolean mBooted = false;
784
785    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
786    int mProcessLimitOverride = -1;
787
788    WindowManagerService mWindowManager;
789
790    static ActivityManagerService mSelf;
791    static ActivityThread mSystemThread;
792
793    private int mCurrentUserId;
794    private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
795    private UserManager mUserManager;
796
797    private final class AppDeathRecipient implements IBinder.DeathRecipient {
798        final ProcessRecord mApp;
799        final int mPid;
800        final IApplicationThread mAppThread;
801
802        AppDeathRecipient(ProcessRecord app, int pid,
803                IApplicationThread thread) {
804            if (localLOGV) Slog.v(
805                TAG, "New death recipient " + this
806                + " for thread " + thread.asBinder());
807            mApp = app;
808            mPid = pid;
809            mAppThread = thread;
810        }
811
812        public void binderDied() {
813            if (localLOGV) Slog.v(
814                TAG, "Death received in " + this
815                + " for thread " + mAppThread.asBinder());
816            synchronized(ActivityManagerService.this) {
817                appDiedLocked(mApp, mPid, mAppThread);
818            }
819        }
820    }
821
822    static final int SHOW_ERROR_MSG = 1;
823    static final int SHOW_NOT_RESPONDING_MSG = 2;
824    static final int SHOW_FACTORY_ERROR_MSG = 3;
825    static final int UPDATE_CONFIGURATION_MSG = 4;
826    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
827    static final int WAIT_FOR_DEBUGGER_MSG = 6;
828    static final int SERVICE_TIMEOUT_MSG = 12;
829    static final int UPDATE_TIME_ZONE = 13;
830    static final int SHOW_UID_ERROR_MSG = 14;
831    static final int IM_FEELING_LUCKY_MSG = 15;
832    static final int PROC_START_TIMEOUT_MSG = 20;
833    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
834    static final int KILL_APPLICATION_MSG = 22;
835    static final int FINALIZE_PENDING_INTENT_MSG = 23;
836    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
837    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
838    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
839    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
840    static final int CLEAR_DNS_CACHE = 28;
841    static final int UPDATE_HTTP_PROXY = 29;
842    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
843    static final int DISPATCH_PROCESSES_CHANGED = 31;
844    static final int DISPATCH_PROCESS_DIED = 32;
845    static final int REPORT_MEM_USAGE = 33;
846
847    static final int FIRST_ACTIVITY_STACK_MSG = 100;
848    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
849    static final int FIRST_COMPAT_MODE_MSG = 300;
850
851    AlertDialog mUidAlert;
852    CompatModeDialog mCompatModeDialog;
853    long mLastMemUsageReportTime = 0;
854
855    final Handler mHandler = new Handler() {
856        //public Handler() {
857        //    if (localLOGV) Slog.v(TAG, "Handler started!");
858        //}
859
860        public void handleMessage(Message msg) {
861            switch (msg.what) {
862            case SHOW_ERROR_MSG: {
863                HashMap data = (HashMap) msg.obj;
864                synchronized (ActivityManagerService.this) {
865                    ProcessRecord proc = (ProcessRecord)data.get("app");
866                    if (proc != null && proc.crashDialog != null) {
867                        Slog.e(TAG, "App already has crash dialog: " + proc);
868                        return;
869                    }
870                    AppErrorResult res = (AppErrorResult) data.get("result");
871                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
872                        Dialog d = new AppErrorDialog(mContext, res, proc);
873                        d.show();
874                        proc.crashDialog = d;
875                    } else {
876                        // The device is asleep, so just pretend that the user
877                        // saw a crash dialog and hit "force quit".
878                        res.set(0);
879                    }
880                }
881
882                ensureBootCompleted();
883            } break;
884            case SHOW_NOT_RESPONDING_MSG: {
885                synchronized (ActivityManagerService.this) {
886                    HashMap data = (HashMap) msg.obj;
887                    ProcessRecord proc = (ProcessRecord)data.get("app");
888                    if (proc != null && proc.anrDialog != null) {
889                        Slog.e(TAG, "App already has anr dialog: " + proc);
890                        return;
891                    }
892
893                    Intent intent = new Intent("android.intent.action.ANR");
894                    if (!mProcessesReady) {
895                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
896                                | Intent.FLAG_RECEIVER_FOREGROUND);
897                    }
898                    broadcastIntentLocked(null, null, intent,
899                            null, null, 0, null, null, null,
900                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
901
902                    if (mShowDialogs) {
903                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
904                                mContext, proc, (ActivityRecord)data.get("activity"));
905                        d.show();
906                        proc.anrDialog = d;
907                    } else {
908                        // Just kill the app if there is no dialog to be shown.
909                        killAppAtUsersRequest(proc, null);
910                    }
911                }
912
913                ensureBootCompleted();
914            } break;
915            case SHOW_STRICT_MODE_VIOLATION_MSG: {
916                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
917                synchronized (ActivityManagerService.this) {
918                    ProcessRecord proc = (ProcessRecord) data.get("app");
919                    if (proc == null) {
920                        Slog.e(TAG, "App not found when showing strict mode dialog.");
921                        break;
922                    }
923                    if (proc.crashDialog != null) {
924                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
925                        return;
926                    }
927                    AppErrorResult res = (AppErrorResult) data.get("result");
928                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
929                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
930                        d.show();
931                        proc.crashDialog = d;
932                    } else {
933                        // The device is asleep, so just pretend that the user
934                        // saw a crash dialog and hit "force quit".
935                        res.set(0);
936                    }
937                }
938                ensureBootCompleted();
939            } break;
940            case SHOW_FACTORY_ERROR_MSG: {
941                Dialog d = new FactoryErrorDialog(
942                    mContext, msg.getData().getCharSequence("msg"));
943                d.show();
944                ensureBootCompleted();
945            } break;
946            case UPDATE_CONFIGURATION_MSG: {
947                final ContentResolver resolver = mContext.getContentResolver();
948                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
949            } break;
950            case GC_BACKGROUND_PROCESSES_MSG: {
951                synchronized (ActivityManagerService.this) {
952                    performAppGcsIfAppropriateLocked();
953                }
954            } break;
955            case WAIT_FOR_DEBUGGER_MSG: {
956                synchronized (ActivityManagerService.this) {
957                    ProcessRecord app = (ProcessRecord)msg.obj;
958                    if (msg.arg1 != 0) {
959                        if (!app.waitedForDebugger) {
960                            Dialog d = new AppWaitingForDebuggerDialog(
961                                    ActivityManagerService.this,
962                                    mContext, app);
963                            app.waitDialog = d;
964                            app.waitedForDebugger = true;
965                            d.show();
966                        }
967                    } else {
968                        if (app.waitDialog != null) {
969                            app.waitDialog.dismiss();
970                            app.waitDialog = null;
971                        }
972                    }
973                }
974            } break;
975            case SERVICE_TIMEOUT_MSG: {
976                if (mDidDexOpt) {
977                    mDidDexOpt = false;
978                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
979                    nmsg.obj = msg.obj;
980                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
981                    return;
982                }
983                mServices.serviceTimeout((ProcessRecord)msg.obj);
984            } break;
985            case UPDATE_TIME_ZONE: {
986                synchronized (ActivityManagerService.this) {
987                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
988                        ProcessRecord r = mLruProcesses.get(i);
989                        if (r.thread != null) {
990                            try {
991                                r.thread.updateTimeZone();
992                            } catch (RemoteException ex) {
993                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
994                            }
995                        }
996                    }
997                }
998            } break;
999            case CLEAR_DNS_CACHE: {
1000                synchronized (ActivityManagerService.this) {
1001                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1002                        ProcessRecord r = mLruProcesses.get(i);
1003                        if (r.thread != null) {
1004                            try {
1005                                r.thread.clearDnsCache();
1006                            } catch (RemoteException ex) {
1007                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1008                            }
1009                        }
1010                    }
1011                }
1012            } break;
1013            case UPDATE_HTTP_PROXY: {
1014                ProxyProperties proxy = (ProxyProperties)msg.obj;
1015                String host = "";
1016                String port = "";
1017                String exclList = "";
1018                if (proxy != null) {
1019                    host = proxy.getHost();
1020                    port = Integer.toString(proxy.getPort());
1021                    exclList = proxy.getExclusionList();
1022                }
1023                synchronized (ActivityManagerService.this) {
1024                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1025                        ProcessRecord r = mLruProcesses.get(i);
1026                        if (r.thread != null) {
1027                            try {
1028                                r.thread.setHttpProxy(host, port, exclList);
1029                            } catch (RemoteException ex) {
1030                                Slog.w(TAG, "Failed to update http proxy for: " +
1031                                        r.info.processName);
1032                            }
1033                        }
1034                    }
1035                }
1036            } break;
1037            case SHOW_UID_ERROR_MSG: {
1038                String title = "System UIDs Inconsistent";
1039                String text = "UIDs on the system are inconsistent, you need to wipe your"
1040                        + " data partition or your device will be unstable.";
1041                Log.e(TAG, title + ": " + text);
1042                if (mShowDialogs) {
1043                    // XXX This is a temporary dialog, no need to localize.
1044                    AlertDialog d = new BaseErrorDialog(mContext);
1045                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1046                    d.setCancelable(false);
1047                    d.setTitle(title);
1048                    d.setMessage(text);
1049                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1050                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1051                    mUidAlert = d;
1052                    d.show();
1053                }
1054            } break;
1055            case IM_FEELING_LUCKY_MSG: {
1056                if (mUidAlert != null) {
1057                    mUidAlert.dismiss();
1058                    mUidAlert = null;
1059                }
1060            } break;
1061            case PROC_START_TIMEOUT_MSG: {
1062                if (mDidDexOpt) {
1063                    mDidDexOpt = false;
1064                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1065                    nmsg.obj = msg.obj;
1066                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1067                    return;
1068                }
1069                ProcessRecord app = (ProcessRecord)msg.obj;
1070                synchronized (ActivityManagerService.this) {
1071                    processStartTimedOutLocked(app);
1072                }
1073            } break;
1074            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1075                synchronized (ActivityManagerService.this) {
1076                    doPendingActivityLaunchesLocked(true);
1077                }
1078            } break;
1079            case KILL_APPLICATION_MSG: {
1080                synchronized (ActivityManagerService.this) {
1081                    int uid = msg.arg1;
1082                    boolean restart = (msg.arg2 == 1);
1083                    String pkg = (String) msg.obj;
1084                    forceStopPackageLocked(pkg, uid, restart, false, true, false,
1085                            UserHandle.getUserId(uid));
1086                }
1087            } break;
1088            case FINALIZE_PENDING_INTENT_MSG: {
1089                ((PendingIntentRecord)msg.obj).completeFinalize();
1090            } break;
1091            case POST_HEAVY_NOTIFICATION_MSG: {
1092                INotificationManager inm = NotificationManager.getService();
1093                if (inm == null) {
1094                    return;
1095                }
1096
1097                ActivityRecord root = (ActivityRecord)msg.obj;
1098                ProcessRecord process = root.app;
1099                if (process == null) {
1100                    return;
1101                }
1102
1103                try {
1104                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1105                    String text = mContext.getString(R.string.heavy_weight_notification,
1106                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1107                    Notification notification = new Notification();
1108                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1109                    notification.when = 0;
1110                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1111                    notification.tickerText = text;
1112                    notification.defaults = 0; // please be quiet
1113                    notification.sound = null;
1114                    notification.vibrate = null;
1115                    notification.setLatestEventInfo(context, text,
1116                            mContext.getText(R.string.heavy_weight_notification_detail),
1117                            PendingIntent.getActivity(mContext, 0, root.intent,
1118                                    PendingIntent.FLAG_CANCEL_CURRENT));
1119
1120                    try {
1121                        int[] outId = new int[1];
1122                        inm.enqueueNotification("android", R.string.heavy_weight_notification,
1123                                notification, outId);
1124                    } catch (RuntimeException e) {
1125                        Slog.w(ActivityManagerService.TAG,
1126                                "Error showing notification for heavy-weight app", e);
1127                    } catch (RemoteException e) {
1128                    }
1129                } catch (NameNotFoundException e) {
1130                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1131                }
1132            } break;
1133            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1134                INotificationManager inm = NotificationManager.getService();
1135                if (inm == null) {
1136                    return;
1137                }
1138                try {
1139                    inm.cancelNotification("android",
1140                            R.string.heavy_weight_notification);
1141                } catch (RuntimeException e) {
1142                    Slog.w(ActivityManagerService.TAG,
1143                            "Error canceling notification for service", e);
1144                } catch (RemoteException e) {
1145                }
1146            } break;
1147            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1148                synchronized (ActivityManagerService.this) {
1149                    checkExcessivePowerUsageLocked(true);
1150                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1151                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1152                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1153                }
1154            } break;
1155            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1156                synchronized (ActivityManagerService.this) {
1157                    ActivityRecord ar = (ActivityRecord)msg.obj;
1158                    if (mCompatModeDialog != null) {
1159                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1160                                ar.info.applicationInfo.packageName)) {
1161                            return;
1162                        }
1163                        mCompatModeDialog.dismiss();
1164                        mCompatModeDialog = null;
1165                    }
1166                    if (ar != null && false) {
1167                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1168                                ar.packageName)) {
1169                            int mode = mCompatModePackages.computeCompatModeLocked(
1170                                    ar.info.applicationInfo);
1171                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1172                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1173                                mCompatModeDialog = new CompatModeDialog(
1174                                        ActivityManagerService.this, mContext,
1175                                        ar.info.applicationInfo);
1176                                mCompatModeDialog.show();
1177                            }
1178                        }
1179                    }
1180                }
1181                break;
1182            }
1183            case DISPATCH_PROCESSES_CHANGED: {
1184                dispatchProcessesChanged();
1185                break;
1186            }
1187            case DISPATCH_PROCESS_DIED: {
1188                final int pid = msg.arg1;
1189                final int uid = msg.arg2;
1190                dispatchProcessDied(pid, uid);
1191                break;
1192            }
1193            case REPORT_MEM_USAGE: {
1194                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1195                if (!isDebuggable) {
1196                    return;
1197                }
1198                synchronized (ActivityManagerService.this) {
1199                    long now = SystemClock.uptimeMillis();
1200                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1201                        // Don't report more than every 5 minutes to somewhat
1202                        // avoid spamming.
1203                        return;
1204                    }
1205                    mLastMemUsageReportTime = now;
1206                }
1207                Thread thread = new Thread() {
1208                    @Override public void run() {
1209                        StringBuilder dropBuilder = new StringBuilder(1024);
1210                        StringBuilder logBuilder = new StringBuilder(1024);
1211                        StringWriter oomSw = new StringWriter();
1212                        PrintWriter oomPw = new PrintWriter(oomSw);
1213                        StringWriter catSw = new StringWriter();
1214                        PrintWriter catPw = new PrintWriter(catSw);
1215                        String[] emptyArgs = new String[] { };
1216                        StringBuilder tag = new StringBuilder(128);
1217                        StringBuilder stack = new StringBuilder(128);
1218                        tag.append("Low on memory -- ");
1219                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1220                                tag, stack);
1221                        dropBuilder.append(stack);
1222                        dropBuilder.append('\n');
1223                        dropBuilder.append('\n');
1224                        String oomString = oomSw.toString();
1225                        dropBuilder.append(oomString);
1226                        dropBuilder.append('\n');
1227                        logBuilder.append(oomString);
1228                        try {
1229                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1230                                    "procrank", });
1231                            final InputStreamReader converter = new InputStreamReader(
1232                                    proc.getInputStream());
1233                            BufferedReader in = new BufferedReader(converter);
1234                            String line;
1235                            while (true) {
1236                                line = in.readLine();
1237                                if (line == null) {
1238                                    break;
1239                                }
1240                                if (line.length() > 0) {
1241                                    logBuilder.append(line);
1242                                    logBuilder.append('\n');
1243                                }
1244                                dropBuilder.append(line);
1245                                dropBuilder.append('\n');
1246                            }
1247                            converter.close();
1248                        } catch (IOException e) {
1249                        }
1250                        synchronized (ActivityManagerService.this) {
1251                            catPw.println();
1252                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1253                            catPw.println();
1254                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1255                                    false, false, null);
1256                            catPw.println();
1257                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1258                        }
1259                        dropBuilder.append(catSw.toString());
1260                        addErrorToDropBox("lowmem", null, "system_server", null,
1261                                null, tag.toString(), dropBuilder.toString(), null, null);
1262                        Slog.i(TAG, logBuilder.toString());
1263                        synchronized (ActivityManagerService.this) {
1264                            long now = SystemClock.uptimeMillis();
1265                            if (mLastMemUsageReportTime < now) {
1266                                mLastMemUsageReportTime = now;
1267                            }
1268                        }
1269                    }
1270                };
1271                thread.start();
1272                break;
1273            }
1274            }
1275        }
1276    };
1277
1278    public static void setSystemProcess() {
1279        try {
1280            ActivityManagerService m = mSelf;
1281
1282            ServiceManager.addService("activity", m, true);
1283            ServiceManager.addService("meminfo", new MemBinder(m));
1284            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1285            ServiceManager.addService("dbinfo", new DbBinder(m));
1286            if (MONITOR_CPU_USAGE) {
1287                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1288            }
1289            ServiceManager.addService("permission", new PermissionController(m));
1290
1291            ApplicationInfo info =
1292                mSelf.mContext.getPackageManager().getApplicationInfo(
1293                            "android", STOCK_PM_FLAGS);
1294            mSystemThread.installSystemApplicationInfo(info);
1295
1296            synchronized (mSelf) {
1297                ProcessRecord app = mSelf.newProcessRecordLocked(
1298                        mSystemThread.getApplicationThread(), info,
1299                        info.processName, false);
1300                app.persistent = true;
1301                app.pid = MY_PID;
1302                app.maxAdj = ProcessList.SYSTEM_ADJ;
1303                mSelf.mProcessNames.put(app.processName, app.uid, app);
1304                synchronized (mSelf.mPidsSelfLocked) {
1305                    mSelf.mPidsSelfLocked.put(app.pid, app);
1306                }
1307                mSelf.updateLruProcessLocked(app, true, true);
1308            }
1309        } catch (PackageManager.NameNotFoundException e) {
1310            throw new RuntimeException(
1311                    "Unable to find android system package", e);
1312        }
1313    }
1314
1315    public void setWindowManager(WindowManagerService wm) {
1316        mWindowManager = wm;
1317    }
1318
1319    public static final Context main(int factoryTest) {
1320        AThread thr = new AThread();
1321        thr.start();
1322
1323        synchronized (thr) {
1324            while (thr.mService == null) {
1325                try {
1326                    thr.wait();
1327                } catch (InterruptedException e) {
1328                }
1329            }
1330        }
1331
1332        ActivityManagerService m = thr.mService;
1333        mSelf = m;
1334        ActivityThread at = ActivityThread.systemMain();
1335        mSystemThread = at;
1336        Context context = at.getSystemContext();
1337        context.setTheme(android.R.style.Theme_Holo);
1338        m.mContext = context;
1339        m.mFactoryTest = factoryTest;
1340        m.mMainStack = new ActivityStack(m, context, true);
1341
1342        m.mBatteryStatsService.publish(context);
1343        m.mUsageStatsService.publish(context);
1344
1345        synchronized (thr) {
1346            thr.mReady = true;
1347            thr.notifyAll();
1348        }
1349
1350        m.startRunning(null, null, null, null);
1351
1352        return context;
1353    }
1354
1355    public static ActivityManagerService self() {
1356        return mSelf;
1357    }
1358
1359    static class AThread extends Thread {
1360        ActivityManagerService mService;
1361        boolean mReady = false;
1362
1363        public AThread() {
1364            super("ActivityManager");
1365        }
1366
1367        public void run() {
1368            Looper.prepare();
1369
1370            android.os.Process.setThreadPriority(
1371                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1372            android.os.Process.setCanSelfBackground(false);
1373
1374            ActivityManagerService m = new ActivityManagerService();
1375
1376            synchronized (this) {
1377                mService = m;
1378                notifyAll();
1379            }
1380
1381            synchronized (this) {
1382                while (!mReady) {
1383                    try {
1384                        wait();
1385                    } catch (InterruptedException e) {
1386                    }
1387                }
1388            }
1389
1390            // For debug builds, log event loop stalls to dropbox for analysis.
1391            if (StrictMode.conditionallyEnableDebugLogging()) {
1392                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1393            }
1394
1395            Looper.loop();
1396        }
1397    }
1398
1399    static class MemBinder extends Binder {
1400        ActivityManagerService mActivityManagerService;
1401        MemBinder(ActivityManagerService activityManagerService) {
1402            mActivityManagerService = activityManagerService;
1403        }
1404
1405        @Override
1406        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1407            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1408                    != PackageManager.PERMISSION_GRANTED) {
1409                pw.println("Permission Denial: can't dump meminfo from from pid="
1410                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1411                        + " without permission " + android.Manifest.permission.DUMP);
1412                return;
1413            }
1414
1415            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1416                    false, null, null, null);
1417        }
1418    }
1419
1420    static class GraphicsBinder extends Binder {
1421        ActivityManagerService mActivityManagerService;
1422        GraphicsBinder(ActivityManagerService activityManagerService) {
1423            mActivityManagerService = activityManagerService;
1424        }
1425
1426        @Override
1427        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1428            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1429                    != PackageManager.PERMISSION_GRANTED) {
1430                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1431                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1432                        + " without permission " + android.Manifest.permission.DUMP);
1433                return;
1434            }
1435
1436            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1437        }
1438    }
1439
1440    static class DbBinder extends Binder {
1441        ActivityManagerService mActivityManagerService;
1442        DbBinder(ActivityManagerService activityManagerService) {
1443            mActivityManagerService = activityManagerService;
1444        }
1445
1446        @Override
1447        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1448            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1449                    != PackageManager.PERMISSION_GRANTED) {
1450                pw.println("Permission Denial: can't dump dbinfo from from pid="
1451                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1452                        + " without permission " + android.Manifest.permission.DUMP);
1453                return;
1454            }
1455
1456            mActivityManagerService.dumpDbInfo(fd, pw, args);
1457        }
1458    }
1459
1460    static class CpuBinder extends Binder {
1461        ActivityManagerService mActivityManagerService;
1462        CpuBinder(ActivityManagerService activityManagerService) {
1463            mActivityManagerService = activityManagerService;
1464        }
1465
1466        @Override
1467        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1468            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1469                    != PackageManager.PERMISSION_GRANTED) {
1470                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1471                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1472                        + " without permission " + android.Manifest.permission.DUMP);
1473                return;
1474            }
1475
1476            synchronized (mActivityManagerService.mProcessStatsThread) {
1477                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1478                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1479                        SystemClock.uptimeMillis()));
1480            }
1481        }
1482    }
1483
1484    private ActivityManagerService() {
1485        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1486
1487        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1488        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1489        mBroadcastQueues[0] = mFgBroadcastQueue;
1490        mBroadcastQueues[1] = mBgBroadcastQueue;
1491
1492        mServices = new ActiveServices(this);
1493
1494        File dataDir = Environment.getDataDirectory();
1495        File systemDir = new File(dataDir, "system");
1496        systemDir.mkdirs();
1497        mBatteryStatsService = new BatteryStatsService(new File(
1498                systemDir, "batterystats.bin").toString());
1499        mBatteryStatsService.getActiveStatistics().readLocked();
1500        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1501        mOnBattery = DEBUG_POWER ? true
1502                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1503        mBatteryStatsService.getActiveStatistics().setCallback(this);
1504
1505        mUsageStatsService = new UsageStatsService(new File(
1506                systemDir, "usagestats").toString());
1507        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1508
1509        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1510            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1511
1512        mConfiguration.setToDefaults();
1513        mConfiguration.locale = Locale.getDefault();
1514        mConfigurationSeq = mConfiguration.seq = 1;
1515        mProcessStats.init();
1516
1517        mCompatModePackages = new CompatModePackages(this, systemDir);
1518
1519        // Add ourself to the Watchdog monitors.
1520        Watchdog.getInstance().addMonitor(this);
1521
1522        mProcessStatsThread = new Thread("ProcessStats") {
1523            public void run() {
1524                while (true) {
1525                    try {
1526                        try {
1527                            synchronized(this) {
1528                                final long now = SystemClock.uptimeMillis();
1529                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1530                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1531                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1532                                //        + ", write delay=" + nextWriteDelay);
1533                                if (nextWriteDelay < nextCpuDelay) {
1534                                    nextCpuDelay = nextWriteDelay;
1535                                }
1536                                if (nextCpuDelay > 0) {
1537                                    mProcessStatsMutexFree.set(true);
1538                                    this.wait(nextCpuDelay);
1539                                }
1540                            }
1541                        } catch (InterruptedException e) {
1542                        }
1543                        updateCpuStatsNow();
1544                    } catch (Exception e) {
1545                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1546                    }
1547                }
1548            }
1549        };
1550        mProcessStatsThread.start();
1551    }
1552
1553    @Override
1554    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1555            throws RemoteException {
1556        if (code == SYSPROPS_TRANSACTION) {
1557            // We need to tell all apps about the system property change.
1558            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1559            synchronized(this) {
1560                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1561                    final int NA = apps.size();
1562                    for (int ia=0; ia<NA; ia++) {
1563                        ProcessRecord app = apps.valueAt(ia);
1564                        if (app.thread != null) {
1565                            procs.add(app.thread.asBinder());
1566                        }
1567                    }
1568                }
1569            }
1570
1571            int N = procs.size();
1572            for (int i=0; i<N; i++) {
1573                Parcel data2 = Parcel.obtain();
1574                try {
1575                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1576                } catch (RemoteException e) {
1577                }
1578                data2.recycle();
1579            }
1580        }
1581        try {
1582            return super.onTransact(code, data, reply, flags);
1583        } catch (RuntimeException e) {
1584            // The activity manager only throws security exceptions, so let's
1585            // log all others.
1586            if (!(e instanceof SecurityException)) {
1587                Slog.e(TAG, "Activity Manager Crash", e);
1588            }
1589            throw e;
1590        }
1591    }
1592
1593    void updateCpuStats() {
1594        final long now = SystemClock.uptimeMillis();
1595        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1596            return;
1597        }
1598        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1599            synchronized (mProcessStatsThread) {
1600                mProcessStatsThread.notify();
1601            }
1602        }
1603    }
1604
1605    void updateCpuStatsNow() {
1606        synchronized (mProcessStatsThread) {
1607            mProcessStatsMutexFree.set(false);
1608            final long now = SystemClock.uptimeMillis();
1609            boolean haveNewCpuStats = false;
1610
1611            if (MONITOR_CPU_USAGE &&
1612                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1613                mLastCpuTime.set(now);
1614                haveNewCpuStats = true;
1615                mProcessStats.update();
1616                //Slog.i(TAG, mProcessStats.printCurrentState());
1617                //Slog.i(TAG, "Total CPU usage: "
1618                //        + mProcessStats.getTotalCpuPercent() + "%");
1619
1620                // Slog the cpu usage if the property is set.
1621                if ("true".equals(SystemProperties.get("events.cpu"))) {
1622                    int user = mProcessStats.getLastUserTime();
1623                    int system = mProcessStats.getLastSystemTime();
1624                    int iowait = mProcessStats.getLastIoWaitTime();
1625                    int irq = mProcessStats.getLastIrqTime();
1626                    int softIrq = mProcessStats.getLastSoftIrqTime();
1627                    int idle = mProcessStats.getLastIdleTime();
1628
1629                    int total = user + system + iowait + irq + softIrq + idle;
1630                    if (total == 0) total = 1;
1631
1632                    EventLog.writeEvent(EventLogTags.CPU,
1633                            ((user+system+iowait+irq+softIrq) * 100) / total,
1634                            (user * 100) / total,
1635                            (system * 100) / total,
1636                            (iowait * 100) / total,
1637                            (irq * 100) / total,
1638                            (softIrq * 100) / total);
1639                }
1640            }
1641
1642            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1643            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1644            synchronized(bstats) {
1645                synchronized(mPidsSelfLocked) {
1646                    if (haveNewCpuStats) {
1647                        if (mOnBattery) {
1648                            int perc = bstats.startAddingCpuLocked();
1649                            int totalUTime = 0;
1650                            int totalSTime = 0;
1651                            final int N = mProcessStats.countStats();
1652                            for (int i=0; i<N; i++) {
1653                                ProcessStats.Stats st = mProcessStats.getStats(i);
1654                                if (!st.working) {
1655                                    continue;
1656                                }
1657                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1658                                int otherUTime = (st.rel_utime*perc)/100;
1659                                int otherSTime = (st.rel_stime*perc)/100;
1660                                totalUTime += otherUTime;
1661                                totalSTime += otherSTime;
1662                                if (pr != null) {
1663                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1664                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1665                                            st.rel_stime-otherSTime);
1666                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1667                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1668                                } else {
1669                                    BatteryStatsImpl.Uid.Proc ps =
1670                                            bstats.getProcessStatsLocked(st.name, st.pid);
1671                                    if (ps != null) {
1672                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1673                                                st.rel_stime-otherSTime);
1674                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1675                                    }
1676                                }
1677                            }
1678                            bstats.finishAddingCpuLocked(perc, totalUTime,
1679                                    totalSTime, cpuSpeedTimes);
1680                        }
1681                    }
1682                }
1683
1684                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1685                    mLastWriteTime = now;
1686                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1687                }
1688            }
1689        }
1690    }
1691
1692    @Override
1693    public void batteryNeedsCpuUpdate() {
1694        updateCpuStatsNow();
1695    }
1696
1697    @Override
1698    public void batteryPowerChanged(boolean onBattery) {
1699        // When plugging in, update the CPU stats first before changing
1700        // the plug state.
1701        updateCpuStatsNow();
1702        synchronized (this) {
1703            synchronized(mPidsSelfLocked) {
1704                mOnBattery = DEBUG_POWER ? true : onBattery;
1705            }
1706        }
1707    }
1708
1709    /**
1710     * Initialize the application bind args. These are passed to each
1711     * process when the bindApplication() IPC is sent to the process. They're
1712     * lazily setup to make sure the services are running when they're asked for.
1713     */
1714    private HashMap<String, IBinder> getCommonServicesLocked() {
1715        if (mAppBindArgs == null) {
1716            mAppBindArgs = new HashMap<String, IBinder>();
1717
1718            // Setup the application init args
1719            mAppBindArgs.put("package", ServiceManager.getService("package"));
1720            mAppBindArgs.put("window", ServiceManager.getService("window"));
1721            mAppBindArgs.put(Context.ALARM_SERVICE,
1722                    ServiceManager.getService(Context.ALARM_SERVICE));
1723        }
1724        return mAppBindArgs;
1725    }
1726
1727    final void setFocusedActivityLocked(ActivityRecord r) {
1728        if (mFocusedActivity != r) {
1729            mFocusedActivity = r;
1730            if (r != null) {
1731                mWindowManager.setFocusedApp(r.appToken, true);
1732            }
1733        }
1734    }
1735
1736    private final void updateLruProcessInternalLocked(ProcessRecord app,
1737            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1738        // put it on the LRU to keep track of when it should be exited.
1739        int lrui = mLruProcesses.indexOf(app);
1740        if (lrui >= 0) mLruProcesses.remove(lrui);
1741
1742        int i = mLruProcesses.size()-1;
1743        int skipTop = 0;
1744
1745        app.lruSeq = mLruSeq;
1746
1747        // compute the new weight for this process.
1748        if (updateActivityTime) {
1749            app.lastActivityTime = SystemClock.uptimeMillis();
1750        }
1751        if (app.activities.size() > 0) {
1752            // If this process has activities, we more strongly want to keep
1753            // it around.
1754            app.lruWeight = app.lastActivityTime;
1755        } else if (app.pubProviders.size() > 0) {
1756            // If this process contains content providers, we want to keep
1757            // it a little more strongly.
1758            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1759            // Also don't let it kick out the first few "real" hidden processes.
1760            skipTop = ProcessList.MIN_HIDDEN_APPS;
1761        } else {
1762            // If this process doesn't have activities, we less strongly
1763            // want to keep it around, and generally want to avoid getting
1764            // in front of any very recently used activities.
1765            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1766            // Also don't let it kick out the first few "real" hidden processes.
1767            skipTop = ProcessList.MIN_HIDDEN_APPS;
1768        }
1769
1770        while (i >= 0) {
1771            ProcessRecord p = mLruProcesses.get(i);
1772            // If this app shouldn't be in front of the first N background
1773            // apps, then skip over that many that are currently hidden.
1774            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1775                skipTop--;
1776            }
1777            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1778                mLruProcesses.add(i+1, app);
1779                break;
1780            }
1781            i--;
1782        }
1783        if (i < 0) {
1784            mLruProcesses.add(0, app);
1785        }
1786
1787        // If the app is currently using a content provider or service,
1788        // bump those processes as well.
1789        if (app.connections.size() > 0) {
1790            for (ConnectionRecord cr : app.connections) {
1791                if (cr.binding != null && cr.binding.service != null
1792                        && cr.binding.service.app != null
1793                        && cr.binding.service.app.lruSeq != mLruSeq) {
1794                    updateLruProcessInternalLocked(cr.binding.service.app, false,
1795                            updateActivityTime, i+1);
1796                }
1797            }
1798        }
1799        for (int j=app.conProviders.size()-1; j>=0; j--) {
1800            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1801            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1802                updateLruProcessInternalLocked(cpr.proc, false,
1803                        updateActivityTime, i+1);
1804            }
1805        }
1806
1807        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1808        if (oomAdj) {
1809            updateOomAdjLocked();
1810        }
1811    }
1812
1813    final void updateLruProcessLocked(ProcessRecord app,
1814            boolean oomAdj, boolean updateActivityTime) {
1815        mLruSeq++;
1816        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1817    }
1818
1819    final ProcessRecord getProcessRecordLocked(
1820            String processName, int uid) {
1821        if (uid == Process.SYSTEM_UID) {
1822            // The system gets to run in any process.  If there are multiple
1823            // processes with the same uid, just pick the first (this
1824            // should never happen).
1825            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1826                    processName);
1827            if (procs == null) return null;
1828            final int N = procs.size();
1829            for (int i = 0; i < N; i++) {
1830                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1831            }
1832        }
1833        ProcessRecord proc = mProcessNames.get(processName, uid);
1834        return proc;
1835    }
1836
1837    void ensurePackageDexOpt(String packageName) {
1838        IPackageManager pm = AppGlobals.getPackageManager();
1839        try {
1840            if (pm.performDexOpt(packageName)) {
1841                mDidDexOpt = true;
1842            }
1843        } catch (RemoteException e) {
1844        }
1845    }
1846
1847    boolean isNextTransitionForward() {
1848        int transit = mWindowManager.getPendingAppTransition();
1849        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1850                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1851                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1852    }
1853
1854    final ProcessRecord startProcessLocked(String processName,
1855            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1856            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1857            boolean isolated) {
1858        ProcessRecord app;
1859        if (!isolated) {
1860            app = getProcessRecordLocked(processName, info.uid);
1861        } else {
1862            // If this is an isolated process, it can't re-use an existing process.
1863            app = null;
1864        }
1865        // We don't have to do anything more if:
1866        // (1) There is an existing application record; and
1867        // (2) The caller doesn't think it is dead, OR there is no thread
1868        //     object attached to it so we know it couldn't have crashed; and
1869        // (3) There is a pid assigned to it, so it is either starting or
1870        //     already running.
1871        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1872                + " app=" + app + " knownToBeDead=" + knownToBeDead
1873                + " thread=" + (app != null ? app.thread : null)
1874                + " pid=" + (app != null ? app.pid : -1));
1875        if (app != null && app.pid > 0) {
1876            if (!knownToBeDead || app.thread == null) {
1877                // We already have the app running, or are waiting for it to
1878                // come up (we have a pid but not yet its thread), so keep it.
1879                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1880                // If this is a new package in the process, add the package to the list
1881                app.addPackage(info.packageName);
1882                return app;
1883            } else {
1884                // An application record is attached to a previous process,
1885                // clean it up now.
1886                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1887                handleAppDiedLocked(app, true, true);
1888            }
1889        }
1890
1891        String hostingNameStr = hostingName != null
1892                ? hostingName.flattenToShortString() : null;
1893
1894        if (!isolated) {
1895            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1896                // If we are in the background, then check to see if this process
1897                // is bad.  If so, we will just silently fail.
1898                if (mBadProcesses.get(info.processName, info.uid) != null) {
1899                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1900                            + "/" + info.processName);
1901                    return null;
1902                }
1903            } else {
1904                // When the user is explicitly starting a process, then clear its
1905                // crash count so that we won't make it bad until they see at
1906                // least one crash dialog again, and make the process good again
1907                // if it had been bad.
1908                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1909                        + "/" + info.processName);
1910                mProcessCrashTimes.remove(info.processName, info.uid);
1911                if (mBadProcesses.get(info.processName, info.uid) != null) {
1912                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1913                            info.processName);
1914                    mBadProcesses.remove(info.processName, info.uid);
1915                    if (app != null) {
1916                        app.bad = false;
1917                    }
1918                }
1919            }
1920        }
1921
1922        if (app == null) {
1923            app = newProcessRecordLocked(null, info, processName, isolated);
1924            if (app == null) {
1925                Slog.w(TAG, "Failed making new process record for "
1926                        + processName + "/" + info.uid + " isolated=" + isolated);
1927                return null;
1928            }
1929            mProcessNames.put(processName, app.uid, app);
1930            if (isolated) {
1931                mIsolatedProcesses.put(app.uid, app);
1932            }
1933        } else {
1934            // If this is a new package in the process, add the package to the list
1935            app.addPackage(info.packageName);
1936        }
1937
1938        // If the system is not ready yet, then hold off on starting this
1939        // process until it is.
1940        if (!mProcessesReady
1941                && !isAllowedWhileBooting(info)
1942                && !allowWhileBooting) {
1943            if (!mProcessesOnHold.contains(app)) {
1944                mProcessesOnHold.add(app);
1945            }
1946            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1947            return app;
1948        }
1949
1950        startProcessLocked(app, hostingType, hostingNameStr);
1951        return (app.pid != 0) ? app : null;
1952    }
1953
1954    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1955        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1956    }
1957
1958    private final void startProcessLocked(ProcessRecord app,
1959            String hostingType, String hostingNameStr) {
1960        if (app.pid > 0 && app.pid != MY_PID) {
1961            synchronized (mPidsSelfLocked) {
1962                mPidsSelfLocked.remove(app.pid);
1963                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1964            }
1965            app.setPid(0);
1966        }
1967
1968        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1969                "startProcessLocked removing on hold: " + app);
1970        mProcessesOnHold.remove(app);
1971
1972        updateCpuStats();
1973
1974        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1975        mProcDeaths[0] = 0;
1976
1977        try {
1978            int uid = app.uid;
1979
1980            int[] gids = null;
1981            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
1982            if (!app.isolated) {
1983                try {
1984                    final PackageManager pm = mContext.getPackageManager();
1985                    gids = pm.getPackageGids(app.info.packageName);
1986                } catch (PackageManager.NameNotFoundException e) {
1987                    Slog.w(TAG, "Unable to retrieve gids", e);
1988                }
1989
1990                if (Environment.isExternalStorageEmulated()) {
1991                    mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
1992                }
1993            }
1994            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1995                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1996                        && mTopComponent != null
1997                        && app.processName.equals(mTopComponent.getPackageName())) {
1998                    uid = 0;
1999                }
2000                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2001                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2002                    uid = 0;
2003                }
2004            }
2005            int debugFlags = 0;
2006            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2007                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2008                // Also turn on CheckJNI for debuggable apps. It's quite
2009                // awkward to turn on otherwise.
2010                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2011            }
2012            // Run the app in safe mode if its manifest requests so or the
2013            // system is booted in safe mode.
2014            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2015                Zygote.systemInSafeMode == true) {
2016                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2017            }
2018            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2019                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2020            }
2021            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2022                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2023            }
2024            if ("1".equals(SystemProperties.get("debug.assert"))) {
2025                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2026            }
2027
2028            // Start the process.  It will either succeed and return a result containing
2029            // the PID of the new process, or else throw a RuntimeException.
2030            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2031                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2032                    app.info.targetSdkVersion, null, null);
2033
2034            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2035            synchronized (bs) {
2036                if (bs.isOnBattery()) {
2037                    app.batteryStats.incStartsLocked();
2038                }
2039            }
2040
2041            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2042                    app.processName, hostingType,
2043                    hostingNameStr != null ? hostingNameStr : "");
2044
2045            if (app.persistent) {
2046                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2047            }
2048
2049            StringBuilder buf = mStringBuilder;
2050            buf.setLength(0);
2051            buf.append("Start proc ");
2052            buf.append(app.processName);
2053            buf.append(" for ");
2054            buf.append(hostingType);
2055            if (hostingNameStr != null) {
2056                buf.append(" ");
2057                buf.append(hostingNameStr);
2058            }
2059            buf.append(": pid=");
2060            buf.append(startResult.pid);
2061            buf.append(" uid=");
2062            buf.append(uid);
2063            buf.append(" gids={");
2064            if (gids != null) {
2065                for (int gi=0; gi<gids.length; gi++) {
2066                    if (gi != 0) buf.append(", ");
2067                    buf.append(gids[gi]);
2068
2069                }
2070            }
2071            buf.append("}");
2072            Slog.i(TAG, buf.toString());
2073            app.setPid(startResult.pid);
2074            app.usingWrapper = startResult.usingWrapper;
2075            app.removed = false;
2076            synchronized (mPidsSelfLocked) {
2077                this.mPidsSelfLocked.put(startResult.pid, app);
2078                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2079                msg.obj = app;
2080                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2081                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2082            }
2083        } catch (RuntimeException e) {
2084            // XXX do better error recovery.
2085            app.setPid(0);
2086            Slog.e(TAG, "Failure starting process " + app.processName, e);
2087        }
2088    }
2089
2090    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2091        if (resumed) {
2092            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2093        } else {
2094            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2095        }
2096    }
2097
2098    boolean startHomeActivityLocked(int userId) {
2099        if (mHeadless) {
2100            // Added because none of the other calls to ensureBootCompleted seem to fire
2101            // when running headless.
2102            ensureBootCompleted();
2103            return false;
2104        }
2105
2106        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2107                && mTopAction == null) {
2108            // We are running in factory test mode, but unable to find
2109            // the factory test app, so just sit around displaying the
2110            // error message and don't try to start anything.
2111            return false;
2112        }
2113        Intent intent = new Intent(
2114            mTopAction,
2115            mTopData != null ? Uri.parse(mTopData) : null);
2116        intent.setComponent(mTopComponent);
2117        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2118            intent.addCategory(Intent.CATEGORY_HOME);
2119        }
2120        ActivityInfo aInfo =
2121            intent.resolveActivityInfo(mContext.getPackageManager(),
2122                    STOCK_PM_FLAGS);
2123        if (aInfo != null) {
2124            intent.setComponent(new ComponentName(
2125                    aInfo.applicationInfo.packageName, aInfo.name));
2126            // Don't do this if the home app is currently being
2127            // instrumented.
2128            aInfo = new ActivityInfo(aInfo);
2129            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2130            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2131                    aInfo.applicationInfo.uid);
2132            if (app == null || app.instrumentationClass == null) {
2133                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2134                mMainStack.startActivityLocked(null, intent, null, aInfo,
2135                        null, null, 0, 0, 0, 0, null, false, null);
2136            }
2137        }
2138
2139        return true;
2140    }
2141
2142    /**
2143     * Starts the "new version setup screen" if appropriate.
2144     */
2145    void startSetupActivityLocked() {
2146        // Only do this once per boot.
2147        if (mCheckedForSetup) {
2148            return;
2149        }
2150
2151        // We will show this screen if the current one is a different
2152        // version than the last one shown, and we are not running in
2153        // low-level factory test mode.
2154        final ContentResolver resolver = mContext.getContentResolver();
2155        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2156                Settings.Secure.getInt(resolver,
2157                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2158            mCheckedForSetup = true;
2159
2160            // See if we should be showing the platform update setup UI.
2161            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2162            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2163                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2164
2165            // We don't allow third party apps to replace this.
2166            ResolveInfo ri = null;
2167            for (int i=0; ris != null && i<ris.size(); i++) {
2168                if ((ris.get(i).activityInfo.applicationInfo.flags
2169                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2170                    ri = ris.get(i);
2171                    break;
2172                }
2173            }
2174
2175            if (ri != null) {
2176                String vers = ri.activityInfo.metaData != null
2177                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2178                        : null;
2179                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2180                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2181                            Intent.METADATA_SETUP_VERSION);
2182                }
2183                String lastVers = Settings.Secure.getString(
2184                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2185                if (vers != null && !vers.equals(lastVers)) {
2186                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2187                    intent.setComponent(new ComponentName(
2188                            ri.activityInfo.packageName, ri.activityInfo.name));
2189                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2190                            null, null, 0, 0, 0, 0, null, false, null);
2191                }
2192            }
2193        }
2194    }
2195
2196    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2197        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2198    }
2199
2200    void enforceNotIsolatedCaller(String caller) {
2201        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2202            throw new SecurityException("Isolated process not allowed to call " + caller);
2203        }
2204    }
2205
2206    public int getFrontActivityScreenCompatMode() {
2207        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2208        synchronized (this) {
2209            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2210        }
2211    }
2212
2213    public void setFrontActivityScreenCompatMode(int mode) {
2214        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2215                "setFrontActivityScreenCompatMode");
2216        synchronized (this) {
2217            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2218        }
2219    }
2220
2221    public int getPackageScreenCompatMode(String packageName) {
2222        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2223        synchronized (this) {
2224            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2225        }
2226    }
2227
2228    public void setPackageScreenCompatMode(String packageName, int mode) {
2229        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2230                "setPackageScreenCompatMode");
2231        synchronized (this) {
2232            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2233        }
2234    }
2235
2236    public boolean getPackageAskScreenCompat(String packageName) {
2237        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2238        synchronized (this) {
2239            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2240        }
2241    }
2242
2243    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2244        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2245                "setPackageAskScreenCompat");
2246        synchronized (this) {
2247            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2248        }
2249    }
2250
2251    void reportResumedActivityLocked(ActivityRecord r) {
2252        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2253        updateUsageStats(r, true);
2254    }
2255
2256    private void dispatchProcessesChanged() {
2257        int N;
2258        synchronized (this) {
2259            N = mPendingProcessChanges.size();
2260            if (mActiveProcessChanges.length < N) {
2261                mActiveProcessChanges = new ProcessChangeItem[N];
2262            }
2263            mPendingProcessChanges.toArray(mActiveProcessChanges);
2264            mAvailProcessChanges.addAll(mPendingProcessChanges);
2265            mPendingProcessChanges.clear();
2266            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2267        }
2268        int i = mProcessObservers.beginBroadcast();
2269        while (i > 0) {
2270            i--;
2271            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2272            if (observer != null) {
2273                try {
2274                    for (int j=0; j<N; j++) {
2275                        ProcessChangeItem item = mActiveProcessChanges[j];
2276                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2277                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2278                                    + item.pid + " uid=" + item.uid + ": "
2279                                    + item.foregroundActivities);
2280                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2281                                    item.foregroundActivities);
2282                        }
2283                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2284                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2285                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2286                            observer.onImportanceChanged(item.pid, item.uid,
2287                                    item.importance);
2288                        }
2289                    }
2290                } catch (RemoteException e) {
2291                }
2292            }
2293        }
2294        mProcessObservers.finishBroadcast();
2295    }
2296
2297    private void dispatchProcessDied(int pid, int uid) {
2298        int i = mProcessObservers.beginBroadcast();
2299        while (i > 0) {
2300            i--;
2301            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2302            if (observer != null) {
2303                try {
2304                    observer.onProcessDied(pid, uid);
2305                } catch (RemoteException e) {
2306                }
2307            }
2308        }
2309        mProcessObservers.finishBroadcast();
2310    }
2311
2312    final void doPendingActivityLaunchesLocked(boolean doResume) {
2313        final int N = mPendingActivityLaunches.size();
2314        if (N <= 0) {
2315            return;
2316        }
2317        for (int i=0; i<N; i++) {
2318            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2319            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2320                    pal.startFlags, doResume && i == (N-1), null);
2321        }
2322        mPendingActivityLaunches.clear();
2323    }
2324
2325    public final int startActivity(IApplicationThread caller,
2326            Intent intent, String resolvedType, IBinder resultTo,
2327            String resultWho, int requestCode, int startFlags,
2328            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2329        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2330                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2331    }
2332
2333    public final int startActivityAsUser(IApplicationThread caller,
2334            Intent intent, String resolvedType, IBinder resultTo,
2335            String resultWho, int requestCode, int startFlags,
2336            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2337        enforceNotIsolatedCaller("startActivity");
2338        if (userId != UserHandle.getCallingUserId()) {
2339            // Requesting a different user, make sure that they have the permission
2340            if (checkComponentPermission(
2341                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2342                    Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
2343                    == PackageManager.PERMISSION_GRANTED) {
2344                // Translate to the current user id, if caller wasn't aware
2345                if (userId == UserHandle.USER_CURRENT) {
2346                    userId = mCurrentUserId;
2347                }
2348            } else {
2349                String msg = "Permission Denial: "
2350                        + "Request to startActivity as user " + userId
2351                        + " but is calling from user " + UserHandle.getCallingUserId()
2352                        + "; this requires "
2353                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
2354                Slog.w(TAG, msg);
2355                throw new SecurityException(msg);
2356            }
2357        } else {
2358            if (intent.getCategories() != null
2359                    && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2360                // Requesting home, set the identity to the current user
2361                // HACK!
2362                userId = mCurrentUserId;
2363            } else {
2364                // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
2365                // the current user's userId
2366                if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
2367                    userId = 0;
2368                } else {
2369                    userId = Binder.getOrigCallingUser();
2370                }
2371            }
2372        }
2373        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2374                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2375                null, null, options, userId);
2376    }
2377
2378    public final WaitResult startActivityAndWait(IApplicationThread caller,
2379            Intent intent, String resolvedType, IBinder resultTo,
2380            String resultWho, int requestCode, int startFlags, String profileFile,
2381            ParcelFileDescriptor profileFd, Bundle options) {
2382        enforceNotIsolatedCaller("startActivityAndWait");
2383        WaitResult res = new WaitResult();
2384        int userId = Binder.getOrigCallingUser();
2385        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2386                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2387                res, null, options, userId);
2388        return res;
2389    }
2390
2391    public final int startActivityWithConfig(IApplicationThread caller,
2392            Intent intent, String resolvedType, IBinder resultTo,
2393            String resultWho, int requestCode, int startFlags, Configuration config,
2394            Bundle options) {
2395        enforceNotIsolatedCaller("startActivityWithConfig");
2396        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2397                resultTo, resultWho, requestCode, startFlags,
2398                null, null, null, config, options, Binder.getOrigCallingUser());
2399        return ret;
2400    }
2401
2402    public int startActivityIntentSender(IApplicationThread caller,
2403            IntentSender intent, Intent fillInIntent, String resolvedType,
2404            IBinder resultTo, String resultWho, int requestCode,
2405            int flagsMask, int flagsValues, Bundle options) {
2406        enforceNotIsolatedCaller("startActivityIntentSender");
2407        // Refuse possible leaked file descriptors
2408        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2409            throw new IllegalArgumentException("File descriptors passed in Intent");
2410        }
2411
2412        IIntentSender sender = intent.getTarget();
2413        if (!(sender instanceof PendingIntentRecord)) {
2414            throw new IllegalArgumentException("Bad PendingIntent object");
2415        }
2416
2417        PendingIntentRecord pir = (PendingIntentRecord)sender;
2418
2419        synchronized (this) {
2420            // If this is coming from the currently resumed activity, it is
2421            // effectively saying that app switches are allowed at this point.
2422            if (mMainStack.mResumedActivity != null
2423                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2424                            Binder.getCallingUid()) {
2425                mAppSwitchesAllowedTime = 0;
2426            }
2427        }
2428        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2429                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2430        return ret;
2431    }
2432
2433    public boolean startNextMatchingActivity(IBinder callingActivity,
2434            Intent intent, Bundle options) {
2435        // Refuse possible leaked file descriptors
2436        if (intent != null && intent.hasFileDescriptors() == true) {
2437            throw new IllegalArgumentException("File descriptors passed in Intent");
2438        }
2439
2440        synchronized (this) {
2441            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2442            if (r == null) {
2443                ActivityOptions.abort(options);
2444                return false;
2445            }
2446            if (r.app == null || r.app.thread == null) {
2447                // The caller is not running...  d'oh!
2448                ActivityOptions.abort(options);
2449                return false;
2450            }
2451            intent = new Intent(intent);
2452            // The caller is not allowed to change the data.
2453            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2454            // And we are resetting to find the next component...
2455            intent.setComponent(null);
2456
2457            ActivityInfo aInfo = null;
2458            try {
2459                List<ResolveInfo> resolves =
2460                    AppGlobals.getPackageManager().queryIntentActivities(
2461                            intent, r.resolvedType,
2462                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2463                            UserHandle.getCallingUserId());
2464
2465                // Look for the original activity in the list...
2466                final int N = resolves != null ? resolves.size() : 0;
2467                for (int i=0; i<N; i++) {
2468                    ResolveInfo rInfo = resolves.get(i);
2469                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2470                            && rInfo.activityInfo.name.equals(r.info.name)) {
2471                        // We found the current one...  the next matching is
2472                        // after it.
2473                        i++;
2474                        if (i<N) {
2475                            aInfo = resolves.get(i).activityInfo;
2476                        }
2477                        break;
2478                    }
2479                }
2480            } catch (RemoteException e) {
2481            }
2482
2483            if (aInfo == null) {
2484                // Nobody who is next!
2485                ActivityOptions.abort(options);
2486                return false;
2487            }
2488
2489            intent.setComponent(new ComponentName(
2490                    aInfo.applicationInfo.packageName, aInfo.name));
2491            intent.setFlags(intent.getFlags()&~(
2492                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2493                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2494                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2495                    Intent.FLAG_ACTIVITY_NEW_TASK));
2496
2497            // Okay now we need to start the new activity, replacing the
2498            // currently running activity.  This is a little tricky because
2499            // we want to start the new one as if the current one is finished,
2500            // but not finish the current one first so that there is no flicker.
2501            // And thus...
2502            final boolean wasFinishing = r.finishing;
2503            r.finishing = true;
2504
2505            // Propagate reply information over to the new activity.
2506            final ActivityRecord resultTo = r.resultTo;
2507            final String resultWho = r.resultWho;
2508            final int requestCode = r.requestCode;
2509            r.resultTo = null;
2510            if (resultTo != null) {
2511                resultTo.removeResultsLocked(r, resultWho, requestCode);
2512            }
2513
2514            final long origId = Binder.clearCallingIdentity();
2515            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2516                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2517                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2518                    options, false, null);
2519            Binder.restoreCallingIdentity(origId);
2520
2521            r.finishing = wasFinishing;
2522            if (res != ActivityManager.START_SUCCESS) {
2523                return false;
2524            }
2525            return true;
2526        }
2527    }
2528
2529    public final int startActivityInPackage(int uid,
2530            Intent intent, String resolvedType, IBinder resultTo,
2531            String resultWho, int requestCode, int startFlags, Bundle options) {
2532
2533        // This is so super not safe, that only the system (or okay root)
2534        // can do it.
2535        final int callingUid = Binder.getCallingUid();
2536        if (callingUid != 0 && callingUid != Process.myUid()) {
2537            throw new SecurityException(
2538                    "startActivityInPackage only available to the system");
2539        }
2540
2541        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2542                resultTo, resultWho, requestCode, startFlags,
2543                null, null, null, null, options, UserHandle.getUserId(uid));
2544        return ret;
2545    }
2546
2547    public final int startActivities(IApplicationThread caller,
2548            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2549        enforceNotIsolatedCaller("startActivities");
2550        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2551                options, Binder.getOrigCallingUser());
2552        return ret;
2553    }
2554
2555    public final int startActivitiesInPackage(int uid,
2556            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2557            Bundle options) {
2558
2559        // This is so super not safe, that only the system (or okay root)
2560        // can do it.
2561        final int callingUid = Binder.getCallingUid();
2562        if (callingUid != 0 && callingUid != Process.myUid()) {
2563            throw new SecurityException(
2564                    "startActivityInPackage only available to the system");
2565        }
2566        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2567                options, UserHandle.getUserId(uid));
2568        return ret;
2569    }
2570
2571    final void addRecentTaskLocked(TaskRecord task) {
2572        int N = mRecentTasks.size();
2573        // Quick case: check if the top-most recent task is the same.
2574        if (N > 0 && mRecentTasks.get(0) == task) {
2575            return;
2576        }
2577        // Remove any existing entries that are the same kind of task.
2578        for (int i=0; i<N; i++) {
2579            TaskRecord tr = mRecentTasks.get(i);
2580            if (task.userId == tr.userId
2581                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2582                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2583                mRecentTasks.remove(i);
2584                i--;
2585                N--;
2586                if (task.intent == null) {
2587                    // If the new recent task we are adding is not fully
2588                    // specified, then replace it with the existing recent task.
2589                    task = tr;
2590                }
2591            }
2592        }
2593        if (N >= MAX_RECENT_TASKS) {
2594            mRecentTasks.remove(N-1);
2595        }
2596        mRecentTasks.add(0, task);
2597    }
2598
2599    public void setRequestedOrientation(IBinder token,
2600            int requestedOrientation) {
2601        synchronized (this) {
2602            ActivityRecord r = mMainStack.isInStackLocked(token);
2603            if (r == null) {
2604                return;
2605            }
2606            final long origId = Binder.clearCallingIdentity();
2607            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2608            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2609                    mConfiguration,
2610                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2611            if (config != null) {
2612                r.frozenBeforeDestroy = true;
2613                if (!updateConfigurationLocked(config, r, false, false)) {
2614                    mMainStack.resumeTopActivityLocked(null);
2615                }
2616            }
2617            Binder.restoreCallingIdentity(origId);
2618        }
2619    }
2620
2621    public int getRequestedOrientation(IBinder token) {
2622        synchronized (this) {
2623            ActivityRecord r = mMainStack.isInStackLocked(token);
2624            if (r == null) {
2625                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2626            }
2627            return mWindowManager.getAppOrientation(r.appToken);
2628        }
2629    }
2630
2631    /**
2632     * This is the internal entry point for handling Activity.finish().
2633     *
2634     * @param token The Binder token referencing the Activity we want to finish.
2635     * @param resultCode Result code, if any, from this Activity.
2636     * @param resultData Result data (Intent), if any, from this Activity.
2637     *
2638     * @return Returns true if the activity successfully finished, or false if it is still running.
2639     */
2640    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2641        // Refuse possible leaked file descriptors
2642        if (resultData != null && resultData.hasFileDescriptors() == true) {
2643            throw new IllegalArgumentException("File descriptors passed in Intent");
2644        }
2645
2646        synchronized(this) {
2647            if (mController != null) {
2648                // Find the first activity that is not finishing.
2649                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2650                if (next != null) {
2651                    // ask watcher if this is allowed
2652                    boolean resumeOK = true;
2653                    try {
2654                        resumeOK = mController.activityResuming(next.packageName);
2655                    } catch (RemoteException e) {
2656                        mController = null;
2657                    }
2658
2659                    if (!resumeOK) {
2660                        return false;
2661                    }
2662                }
2663            }
2664            final long origId = Binder.clearCallingIdentity();
2665            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2666                    resultData, "app-request");
2667            Binder.restoreCallingIdentity(origId);
2668            return res;
2669        }
2670    }
2671
2672    public final void finishHeavyWeightApp() {
2673        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2674                != PackageManager.PERMISSION_GRANTED) {
2675            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2676                    + Binder.getCallingPid()
2677                    + ", uid=" + Binder.getCallingUid()
2678                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2679            Slog.w(TAG, msg);
2680            throw new SecurityException(msg);
2681        }
2682
2683        synchronized(this) {
2684            if (mHeavyWeightProcess == null) {
2685                return;
2686            }
2687
2688            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2689                    mHeavyWeightProcess.activities);
2690            for (int i=0; i<activities.size(); i++) {
2691                ActivityRecord r = activities.get(i);
2692                if (!r.finishing) {
2693                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2694                    if (index >= 0) {
2695                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2696                                null, "finish-heavy");
2697                    }
2698                }
2699            }
2700
2701            mHeavyWeightProcess = null;
2702            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2703        }
2704    }
2705
2706    public void crashApplication(int uid, int initialPid, String packageName,
2707            String message) {
2708        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2709                != PackageManager.PERMISSION_GRANTED) {
2710            String msg = "Permission Denial: crashApplication() from pid="
2711                    + Binder.getCallingPid()
2712                    + ", uid=" + Binder.getCallingUid()
2713                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2714            Slog.w(TAG, msg);
2715            throw new SecurityException(msg);
2716        }
2717
2718        synchronized(this) {
2719            ProcessRecord proc = null;
2720
2721            // Figure out which process to kill.  We don't trust that initialPid
2722            // still has any relation to current pids, so must scan through the
2723            // list.
2724            synchronized (mPidsSelfLocked) {
2725                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2726                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2727                    if (p.uid != uid) {
2728                        continue;
2729                    }
2730                    if (p.pid == initialPid) {
2731                        proc = p;
2732                        break;
2733                    }
2734                    for (String str : p.pkgList) {
2735                        if (str.equals(packageName)) {
2736                            proc = p;
2737                        }
2738                    }
2739                }
2740            }
2741
2742            if (proc == null) {
2743                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2744                        + " initialPid=" + initialPid
2745                        + " packageName=" + packageName);
2746                return;
2747            }
2748
2749            if (proc.thread != null) {
2750                if (proc.pid == Process.myPid()) {
2751                    Log.w(TAG, "crashApplication: trying to crash self!");
2752                    return;
2753                }
2754                long ident = Binder.clearCallingIdentity();
2755                try {
2756                    proc.thread.scheduleCrash(message);
2757                } catch (RemoteException e) {
2758                }
2759                Binder.restoreCallingIdentity(ident);
2760            }
2761        }
2762    }
2763
2764    public final void finishSubActivity(IBinder token, String resultWho,
2765            int requestCode) {
2766        synchronized(this) {
2767            final long origId = Binder.clearCallingIdentity();
2768            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2769            Binder.restoreCallingIdentity(origId);
2770        }
2771    }
2772
2773    public boolean finishActivityAffinity(IBinder token) {
2774        synchronized(this) {
2775            final long origId = Binder.clearCallingIdentity();
2776            boolean res = mMainStack.finishActivityAffinityLocked(token);
2777            Binder.restoreCallingIdentity(origId);
2778            return res;
2779        }
2780    }
2781
2782    public boolean willActivityBeVisible(IBinder token) {
2783        synchronized(this) {
2784            int i;
2785            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2786                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2787                if (r.appToken == token) {
2788                    return true;
2789                }
2790                if (r.fullscreen && !r.finishing) {
2791                    return false;
2792                }
2793            }
2794            return true;
2795        }
2796    }
2797
2798    public void overridePendingTransition(IBinder token, String packageName,
2799            int enterAnim, int exitAnim) {
2800        synchronized(this) {
2801            ActivityRecord self = mMainStack.isInStackLocked(token);
2802            if (self == null) {
2803                return;
2804            }
2805
2806            final long origId = Binder.clearCallingIdentity();
2807
2808            if (self.state == ActivityState.RESUMED
2809                    || self.state == ActivityState.PAUSING) {
2810                mWindowManager.overridePendingAppTransition(packageName,
2811                        enterAnim, exitAnim, null);
2812            }
2813
2814            Binder.restoreCallingIdentity(origId);
2815        }
2816    }
2817
2818    /**
2819     * Main function for removing an existing process from the activity manager
2820     * as a result of that process going away.  Clears out all connections
2821     * to the process.
2822     */
2823    private final void handleAppDiedLocked(ProcessRecord app,
2824            boolean restarting, boolean allowRestart) {
2825        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2826        if (!restarting) {
2827            mLruProcesses.remove(app);
2828        }
2829
2830        if (mProfileProc == app) {
2831            clearProfilerLocked();
2832        }
2833
2834        // Just in case...
2835        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2836            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2837            mMainStack.mPausingActivity = null;
2838        }
2839        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2840            mMainStack.mLastPausedActivity = null;
2841        }
2842
2843        // Remove this application's activities from active lists.
2844        mMainStack.removeHistoryRecordsForAppLocked(app);
2845
2846        boolean atTop = true;
2847        boolean hasVisibleActivities = false;
2848
2849        // Clean out the history list.
2850        int i = mMainStack.mHistory.size();
2851        if (localLOGV) Slog.v(
2852            TAG, "Removing app " + app + " from history with " + i + " entries");
2853        while (i > 0) {
2854            i--;
2855            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2856            if (localLOGV) Slog.v(
2857                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2858            if (r.app == app) {
2859                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2860                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2861                        RuntimeException here = new RuntimeException("here");
2862                        here.fillInStackTrace();
2863                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2864                                + ": haveState=" + r.haveState
2865                                + " stateNotNeeded=" + r.stateNotNeeded
2866                                + " finishing=" + r.finishing
2867                                + " state=" + r.state, here);
2868                    }
2869                    if (!r.finishing) {
2870                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2871                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2872                                System.identityHashCode(r),
2873                                r.task.taskId, r.shortComponentName,
2874                                "proc died without state saved");
2875                    }
2876                    mMainStack.removeActivityFromHistoryLocked(r);
2877
2878                } else {
2879                    // We have the current state for this activity, so
2880                    // it can be restarted later when needed.
2881                    if (localLOGV) Slog.v(
2882                        TAG, "Keeping entry, setting app to null");
2883                    if (r.visible) {
2884                        hasVisibleActivities = true;
2885                    }
2886                    r.app = null;
2887                    r.nowVisible = false;
2888                    if (!r.haveState) {
2889                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2890                                "App died, clearing saved state of " + r);
2891                        r.icicle = null;
2892                    }
2893                }
2894
2895                r.stack.cleanUpActivityLocked(r, true, true);
2896            }
2897            atTop = false;
2898        }
2899
2900        app.activities.clear();
2901
2902        if (app.instrumentationClass != null) {
2903            Slog.w(TAG, "Crash of app " + app.processName
2904                  + " running instrumentation " + app.instrumentationClass);
2905            Bundle info = new Bundle();
2906            info.putString("shortMsg", "Process crashed.");
2907            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2908        }
2909
2910        if (!restarting) {
2911            if (!mMainStack.resumeTopActivityLocked(null)) {
2912                // If there was nothing to resume, and we are not already
2913                // restarting this process, but there is a visible activity that
2914                // is hosted by the process...  then make sure all visible
2915                // activities are running, taking care of restarting this
2916                // process.
2917                if (hasVisibleActivities) {
2918                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2919                }
2920            }
2921        }
2922    }
2923
2924    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2925        IBinder threadBinder = thread.asBinder();
2926        // Find the application record.
2927        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2928            ProcessRecord rec = mLruProcesses.get(i);
2929            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2930                return i;
2931            }
2932        }
2933        return -1;
2934    }
2935
2936    final ProcessRecord getRecordForAppLocked(
2937            IApplicationThread thread) {
2938        if (thread == null) {
2939            return null;
2940        }
2941
2942        int appIndex = getLRURecordIndexForAppLocked(thread);
2943        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2944    }
2945
2946    final void appDiedLocked(ProcessRecord app, int pid,
2947            IApplicationThread thread) {
2948
2949        mProcDeaths[0]++;
2950
2951        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2952        synchronized (stats) {
2953            stats.noteProcessDiedLocked(app.info.uid, pid);
2954        }
2955
2956        // Clean up already done if the process has been re-started.
2957        if (app.pid == pid && app.thread != null &&
2958                app.thread.asBinder() == thread.asBinder()) {
2959            if (!app.killedBackground) {
2960                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2961                        + ") has died.");
2962            }
2963            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2964            if (localLOGV) Slog.v(
2965                TAG, "Dying app: " + app + ", pid: " + pid
2966                + ", thread: " + thread.asBinder());
2967            boolean doLowMem = app.instrumentationClass == null;
2968            handleAppDiedLocked(app, false, true);
2969
2970            if (doLowMem) {
2971                // If there are no longer any background processes running,
2972                // and the app that died was not running instrumentation,
2973                // then tell everyone we are now low on memory.
2974                boolean haveBg = false;
2975                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2976                    ProcessRecord rec = mLruProcesses.get(i);
2977                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2978                        haveBg = true;
2979                        break;
2980                    }
2981                }
2982
2983                if (!haveBg) {
2984                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2985                    long now = SystemClock.uptimeMillis();
2986                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2987                        ProcessRecord rec = mLruProcesses.get(i);
2988                        if (rec != app && rec.thread != null &&
2989                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2990                            // The low memory report is overriding any current
2991                            // state for a GC request.  Make sure to do
2992                            // heavy/important/visible/foreground processes first.
2993                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
2994                                rec.lastRequestedGc = 0;
2995                            } else {
2996                                rec.lastRequestedGc = rec.lastLowMemory;
2997                            }
2998                            rec.reportLowMemory = true;
2999                            rec.lastLowMemory = now;
3000                            mProcessesToGc.remove(rec);
3001                            addProcessToGcListLocked(rec);
3002                        }
3003                    }
3004                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3005                    scheduleAppGcsLocked();
3006                }
3007            }
3008        } else if (app.pid != pid) {
3009            // A new process has already been started.
3010            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3011                    + ") has died and restarted (pid " + app.pid + ").");
3012            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3013        } else if (DEBUG_PROCESSES) {
3014            Slog.d(TAG, "Received spurious death notification for thread "
3015                    + thread.asBinder());
3016        }
3017    }
3018
3019    /**
3020     * If a stack trace dump file is configured, dump process stack traces.
3021     * @param clearTraces causes the dump file to be erased prior to the new
3022     *    traces being written, if true; when false, the new traces will be
3023     *    appended to any existing file content.
3024     * @param firstPids of dalvik VM processes to dump stack traces for first
3025     * @param lastPids of dalvik VM processes to dump stack traces for last
3026     * @param nativeProcs optional list of native process names to dump stack crawls
3027     * @return file containing stack traces, or null if no dump file is configured
3028     */
3029    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3030            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3031        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3032        if (tracesPath == null || tracesPath.length() == 0) {
3033            return null;
3034        }
3035
3036        File tracesFile = new File(tracesPath);
3037        try {
3038            File tracesDir = tracesFile.getParentFile();
3039            if (!tracesDir.exists()) {
3040                tracesFile.mkdirs();
3041                if (!SELinux.restorecon(tracesDir)) {
3042                    return null;
3043                }
3044            }
3045            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3046
3047            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3048            tracesFile.createNewFile();
3049            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3050        } catch (IOException e) {
3051            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3052            return null;
3053        }
3054
3055        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3056        return tracesFile;
3057    }
3058
3059    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3060            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3061        // Use a FileObserver to detect when traces finish writing.
3062        // The order of traces is considered important to maintain for legibility.
3063        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3064            public synchronized void onEvent(int event, String path) { notify(); }
3065        };
3066
3067        try {
3068            observer.startWatching();
3069
3070            // First collect all of the stacks of the most important pids.
3071            if (firstPids != null) {
3072                try {
3073                    int num = firstPids.size();
3074                    for (int i = 0; i < num; i++) {
3075                        synchronized (observer) {
3076                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3077                            observer.wait(200);  // Wait for write-close, give up after 200msec
3078                        }
3079                    }
3080                } catch (InterruptedException e) {
3081                    Log.wtf(TAG, e);
3082                }
3083            }
3084
3085            // Next measure CPU usage.
3086            if (processStats != null) {
3087                processStats.init();
3088                System.gc();
3089                processStats.update();
3090                try {
3091                    synchronized (processStats) {
3092                        processStats.wait(500); // measure over 1/2 second.
3093                    }
3094                } catch (InterruptedException e) {
3095                }
3096                processStats.update();
3097
3098                // We'll take the stack crawls of just the top apps using CPU.
3099                final int N = processStats.countWorkingStats();
3100                int numProcs = 0;
3101                for (int i=0; i<N && numProcs<5; i++) {
3102                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3103                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3104                        numProcs++;
3105                        try {
3106                            synchronized (observer) {
3107                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3108                                observer.wait(200);  // Wait for write-close, give up after 200msec
3109                            }
3110                        } catch (InterruptedException e) {
3111                            Log.wtf(TAG, e);
3112                        }
3113
3114                    }
3115                }
3116            }
3117
3118        } finally {
3119            observer.stopWatching();
3120        }
3121
3122        if (nativeProcs != null) {
3123            int[] pids = Process.getPidsForCommands(nativeProcs);
3124            if (pids != null) {
3125                for (int pid : pids) {
3126                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3127                }
3128            }
3129        }
3130    }
3131
3132    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3133        if (true || IS_USER_BUILD) {
3134            return;
3135        }
3136        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3137        if (tracesPath == null || tracesPath.length() == 0) {
3138            return;
3139        }
3140
3141        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3142        StrictMode.allowThreadDiskWrites();
3143        try {
3144            final File tracesFile = new File(tracesPath);
3145            final File tracesDir = tracesFile.getParentFile();
3146            final File tracesTmp = new File(tracesDir, "__tmp__");
3147            try {
3148                if (!tracesDir.exists()) {
3149                    tracesFile.mkdirs();
3150                    if (!SELinux.restorecon(tracesDir.getPath())) {
3151                        return;
3152                    }
3153                }
3154                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3155
3156                if (tracesFile.exists()) {
3157                    tracesTmp.delete();
3158                    tracesFile.renameTo(tracesTmp);
3159                }
3160                StringBuilder sb = new StringBuilder();
3161                Time tobj = new Time();
3162                tobj.set(System.currentTimeMillis());
3163                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3164                sb.append(": ");
3165                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3166                sb.append(" since ");
3167                sb.append(msg);
3168                FileOutputStream fos = new FileOutputStream(tracesFile);
3169                fos.write(sb.toString().getBytes());
3170                if (app == null) {
3171                    fos.write("\n*** No application process!".getBytes());
3172                }
3173                fos.close();
3174                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3175            } catch (IOException e) {
3176                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3177                return;
3178            }
3179
3180            if (app != null) {
3181                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3182                firstPids.add(app.pid);
3183                dumpStackTraces(tracesPath, firstPids, null, null, null);
3184            }
3185
3186            File lastTracesFile = null;
3187            File curTracesFile = null;
3188            for (int i=9; i>=0; i--) {
3189                String name = String.format("slow%02d.txt", i);
3190                curTracesFile = new File(tracesDir, name);
3191                if (curTracesFile.exists()) {
3192                    if (lastTracesFile != null) {
3193                        curTracesFile.renameTo(lastTracesFile);
3194                    } else {
3195                        curTracesFile.delete();
3196                    }
3197                }
3198                lastTracesFile = curTracesFile;
3199            }
3200            tracesFile.renameTo(curTracesFile);
3201            if (tracesTmp.exists()) {
3202                tracesTmp.renameTo(tracesFile);
3203            }
3204        } finally {
3205            StrictMode.setThreadPolicy(oldPolicy);
3206        }
3207    }
3208
3209    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3210            ActivityRecord parent, final String annotation) {
3211        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3212        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3213
3214        if (mController != null) {
3215            try {
3216                // 0 == continue, -1 = kill process immediately
3217                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3218                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3219            } catch (RemoteException e) {
3220                mController = null;
3221            }
3222        }
3223
3224        long anrTime = SystemClock.uptimeMillis();
3225        if (MONITOR_CPU_USAGE) {
3226            updateCpuStatsNow();
3227        }
3228
3229        synchronized (this) {
3230            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3231            if (mShuttingDown) {
3232                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3233                return;
3234            } else if (app.notResponding) {
3235                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3236                return;
3237            } else if (app.crashing) {
3238                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3239                return;
3240            }
3241
3242            // In case we come through here for the same app before completing
3243            // this one, mark as anring now so we will bail out.
3244            app.notResponding = true;
3245
3246            // Log the ANR to the event log.
3247            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3248                    annotation);
3249
3250            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3251            firstPids.add(app.pid);
3252
3253            int parentPid = app.pid;
3254            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3255            if (parentPid != app.pid) firstPids.add(parentPid);
3256
3257            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3258
3259            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3260                ProcessRecord r = mLruProcesses.get(i);
3261                if (r != null && r.thread != null) {
3262                    int pid = r.pid;
3263                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3264                        if (r.persistent) {
3265                            firstPids.add(pid);
3266                        } else {
3267                            lastPids.put(pid, Boolean.TRUE);
3268                        }
3269                    }
3270                }
3271            }
3272        }
3273
3274        // Log the ANR to the main log.
3275        StringBuilder info = new StringBuilder();
3276        info.setLength(0);
3277        info.append("ANR in ").append(app.processName);
3278        if (activity != null && activity.shortComponentName != null) {
3279            info.append(" (").append(activity.shortComponentName).append(")");
3280        }
3281        info.append("\n");
3282        if (annotation != null) {
3283            info.append("Reason: ").append(annotation).append("\n");
3284        }
3285        if (parent != null && parent != activity) {
3286            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3287        }
3288
3289        final ProcessStats processStats = new ProcessStats(true);
3290
3291        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3292
3293        String cpuInfo = null;
3294        if (MONITOR_CPU_USAGE) {
3295            updateCpuStatsNow();
3296            synchronized (mProcessStatsThread) {
3297                cpuInfo = mProcessStats.printCurrentState(anrTime);
3298            }
3299            info.append(processStats.printCurrentLoad());
3300            info.append(cpuInfo);
3301        }
3302
3303        info.append(processStats.printCurrentState(anrTime));
3304
3305        Slog.e(TAG, info.toString());
3306        if (tracesFile == null) {
3307            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3308            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3309        }
3310
3311        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3312                cpuInfo, tracesFile, null);
3313
3314        if (mController != null) {
3315            try {
3316                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3317                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3318                if (res != 0) {
3319                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3320                    return;
3321                }
3322            } catch (RemoteException e) {
3323                mController = null;
3324            }
3325        }
3326
3327        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3328        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3329                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3330
3331        synchronized (this) {
3332            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3333                Slog.w(TAG, "Killing " + app + ": background ANR");
3334                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3335                        app.processName, app.setAdj, "background ANR");
3336                Process.killProcessQuiet(app.pid);
3337                return;
3338            }
3339
3340            // Set the app's notResponding state, and look up the errorReportReceiver
3341            makeAppNotRespondingLocked(app,
3342                    activity != null ? activity.shortComponentName : null,
3343                    annotation != null ? "ANR " + annotation : "ANR",
3344                    info.toString());
3345
3346            // Bring up the infamous App Not Responding dialog
3347            Message msg = Message.obtain();
3348            HashMap map = new HashMap();
3349            msg.what = SHOW_NOT_RESPONDING_MSG;
3350            msg.obj = map;
3351            map.put("app", app);
3352            if (activity != null) {
3353                map.put("activity", activity);
3354            }
3355
3356            mHandler.sendMessage(msg);
3357        }
3358    }
3359
3360    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3361        if (!mLaunchWarningShown) {
3362            mLaunchWarningShown = true;
3363            mHandler.post(new Runnable() {
3364                @Override
3365                public void run() {
3366                    synchronized (ActivityManagerService.this) {
3367                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3368                        d.show();
3369                        mHandler.postDelayed(new Runnable() {
3370                            @Override
3371                            public void run() {
3372                                synchronized (ActivityManagerService.this) {
3373                                    d.dismiss();
3374                                    mLaunchWarningShown = false;
3375                                }
3376                            }
3377                        }, 4000);
3378                    }
3379                }
3380            });
3381        }
3382    }
3383
3384    public boolean clearApplicationUserData(final String packageName,
3385            final IPackageDataObserver observer, final int userId) {
3386        enforceNotIsolatedCaller("clearApplicationUserData");
3387        int uid = Binder.getCallingUid();
3388        int pid = Binder.getCallingPid();
3389        long callingId = Binder.clearCallingIdentity();
3390        try {
3391            IPackageManager pm = AppGlobals.getPackageManager();
3392            int pkgUid = -1;
3393            synchronized(this) {
3394                try {
3395                    pkgUid = pm.getPackageUid(packageName, userId);
3396                } catch (RemoteException e) {
3397                }
3398                if (pkgUid == -1) {
3399                    Slog.w(TAG, "Invalid packageName:" + packageName);
3400                    return false;
3401                }
3402                if (uid == pkgUid || checkComponentPermission(
3403                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3404                        pid, uid, -1, true)
3405                        == PackageManager.PERMISSION_GRANTED) {
3406                    forceStopPackageLocked(packageName, pkgUid);
3407                } else {
3408                    throw new SecurityException(pid+" does not have permission:"+
3409                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3410                                    "for process:"+packageName);
3411                }
3412            }
3413
3414            try {
3415                //clear application user data
3416                pm.clearApplicationUserData(packageName, observer, userId);
3417                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3418                        Uri.fromParts("package", packageName, null));
3419                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3420                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3421                        null, null, 0, null, null, null, false, false, userId);
3422            } catch (RemoteException e) {
3423            }
3424        } finally {
3425            Binder.restoreCallingIdentity(callingId);
3426        }
3427        return true;
3428    }
3429
3430    public void killBackgroundProcesses(final String packageName) {
3431        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3432                != PackageManager.PERMISSION_GRANTED &&
3433                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3434                        != PackageManager.PERMISSION_GRANTED) {
3435            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3436                    + Binder.getCallingPid()
3437                    + ", uid=" + Binder.getCallingUid()
3438                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3439            Slog.w(TAG, msg);
3440            throw new SecurityException(msg);
3441        }
3442
3443        int userId = UserHandle.getCallingUserId();
3444        long callingId = Binder.clearCallingIdentity();
3445        try {
3446            IPackageManager pm = AppGlobals.getPackageManager();
3447            int pkgUid = -1;
3448            synchronized(this) {
3449                try {
3450                    pkgUid = pm.getPackageUid(packageName, userId);
3451                } catch (RemoteException e) {
3452                }
3453                if (pkgUid == -1) {
3454                    Slog.w(TAG, "Invalid packageName: " + packageName);
3455                    return;
3456                }
3457                killPackageProcessesLocked(packageName, pkgUid,
3458                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3459            }
3460        } finally {
3461            Binder.restoreCallingIdentity(callingId);
3462        }
3463    }
3464
3465    public void killAllBackgroundProcesses() {
3466        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3467                != PackageManager.PERMISSION_GRANTED) {
3468            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3469                    + Binder.getCallingPid()
3470                    + ", uid=" + Binder.getCallingUid()
3471                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3472            Slog.w(TAG, msg);
3473            throw new SecurityException(msg);
3474        }
3475
3476        long callingId = Binder.clearCallingIdentity();
3477        try {
3478            synchronized(this) {
3479                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3480                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3481                    final int NA = apps.size();
3482                    for (int ia=0; ia<NA; ia++) {
3483                        ProcessRecord app = apps.valueAt(ia);
3484                        if (app.persistent) {
3485                            // we don't kill persistent processes
3486                            continue;
3487                        }
3488                        if (app.removed) {
3489                            procs.add(app);
3490                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3491                            app.removed = true;
3492                            procs.add(app);
3493                        }
3494                    }
3495                }
3496
3497                int N = procs.size();
3498                for (int i=0; i<N; i++) {
3499                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3500                }
3501            }
3502        } finally {
3503            Binder.restoreCallingIdentity(callingId);
3504        }
3505    }
3506
3507    public void forceStopPackage(final String packageName) {
3508        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3509                != PackageManager.PERMISSION_GRANTED) {
3510            String msg = "Permission Denial: forceStopPackage() from pid="
3511                    + Binder.getCallingPid()
3512                    + ", uid=" + Binder.getCallingUid()
3513                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3514            Slog.w(TAG, msg);
3515            throw new SecurityException(msg);
3516        }
3517        final int userId = UserHandle.getCallingUserId();
3518        long callingId = Binder.clearCallingIdentity();
3519        try {
3520            IPackageManager pm = AppGlobals.getPackageManager();
3521            int pkgUid = -1;
3522            synchronized(this) {
3523                try {
3524                    pkgUid = pm.getPackageUid(packageName, userId);
3525                } catch (RemoteException e) {
3526                }
3527                if (pkgUid == -1) {
3528                    Slog.w(TAG, "Invalid packageName: " + packageName);
3529                    return;
3530                }
3531                forceStopPackageLocked(packageName, pkgUid);
3532                try {
3533                    pm.setPackageStoppedState(packageName, true, userId);
3534                } catch (RemoteException e) {
3535                } catch (IllegalArgumentException e) {
3536                    Slog.w(TAG, "Failed trying to unstop package "
3537                            + packageName + ": " + e);
3538                }
3539            }
3540        } finally {
3541            Binder.restoreCallingIdentity(callingId);
3542        }
3543    }
3544
3545    /*
3546     * The pkg name and uid have to be specified.
3547     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3548     */
3549    public void killApplicationWithUid(String pkg, int uid) {
3550        if (pkg == null) {
3551            return;
3552        }
3553        // Make sure the uid is valid.
3554        if (uid < 0) {
3555            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3556            return;
3557        }
3558        int callerUid = Binder.getCallingUid();
3559        // Only the system server can kill an application
3560        if (callerUid == Process.SYSTEM_UID) {
3561            // Post an aysnc message to kill the application
3562            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3563            msg.arg1 = uid;
3564            msg.arg2 = 0;
3565            msg.obj = pkg;
3566            mHandler.sendMessage(msg);
3567        } else {
3568            throw new SecurityException(callerUid + " cannot kill pkg: " +
3569                    pkg);
3570        }
3571    }
3572
3573    public void closeSystemDialogs(String reason) {
3574        enforceNotIsolatedCaller("closeSystemDialogs");
3575
3576        final int uid = Binder.getCallingUid();
3577        final long origId = Binder.clearCallingIdentity();
3578        synchronized (this) {
3579            closeSystemDialogsLocked(uid, reason);
3580        }
3581        Binder.restoreCallingIdentity(origId);
3582    }
3583
3584    void closeSystemDialogsLocked(int callingUid, String reason) {
3585        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3586        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3587        if (reason != null) {
3588            intent.putExtra("reason", reason);
3589        }
3590        mWindowManager.closeSystemDialogs(reason);
3591
3592        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3593            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3594            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3595                r.stack.finishActivityLocked(r, i,
3596                        Activity.RESULT_CANCELED, null, "close-sys");
3597            }
3598        }
3599
3600        broadcastIntentLocked(null, null, intent, null,
3601                null, 0, null, null, null, false, false, -1,
3602                callingUid, 0 /* TODO: Verify */);
3603    }
3604
3605    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3606            throws RemoteException {
3607        enforceNotIsolatedCaller("getProcessMemoryInfo");
3608        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3609        for (int i=pids.length-1; i>=0; i--) {
3610            infos[i] = new Debug.MemoryInfo();
3611            Debug.getMemoryInfo(pids[i], infos[i]);
3612        }
3613        return infos;
3614    }
3615
3616    public long[] getProcessPss(int[] pids) throws RemoteException {
3617        enforceNotIsolatedCaller("getProcessPss");
3618        long[] pss = new long[pids.length];
3619        for (int i=pids.length-1; i>=0; i--) {
3620            pss[i] = Debug.getPss(pids[i]);
3621        }
3622        return pss;
3623    }
3624
3625    public void killApplicationProcess(String processName, int uid) {
3626        if (processName == null) {
3627            return;
3628        }
3629
3630        int callerUid = Binder.getCallingUid();
3631        // Only the system server can kill an application
3632        if (callerUid == Process.SYSTEM_UID) {
3633            synchronized (this) {
3634                ProcessRecord app = getProcessRecordLocked(processName, uid);
3635                if (app != null && app.thread != null) {
3636                    try {
3637                        app.thread.scheduleSuicide();
3638                    } catch (RemoteException e) {
3639                        // If the other end already died, then our work here is done.
3640                    }
3641                } else {
3642                    Slog.w(TAG, "Process/uid not found attempting kill of "
3643                            + processName + " / " + uid);
3644                }
3645            }
3646        } else {
3647            throw new SecurityException(callerUid + " cannot kill app process: " +
3648                    processName);
3649        }
3650    }
3651
3652    private void forceStopPackageLocked(final String packageName, int uid) {
3653        forceStopPackageLocked(packageName, uid, false, false, true, false, UserHandle.getUserId(uid));
3654        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3655                Uri.fromParts("package", packageName, null));
3656        if (!mProcessesReady) {
3657            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3658        }
3659        intent.putExtra(Intent.EXTRA_UID, uid);
3660        broadcastIntentLocked(null, null, intent,
3661                null, null, 0, null, null, null,
3662                false, false,
3663                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3664    }
3665
3666    private final boolean killPackageProcessesLocked(String packageName, int uid,
3667            int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3668            boolean evenPersistent, String reason) {
3669        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3670
3671        // Remove all processes this package may have touched: all with the
3672        // same UID (except for the system or root user), and all whose name
3673        // matches the package name.
3674        final String procNamePrefix = packageName + ":";
3675        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3676            final int NA = apps.size();
3677            for (int ia=0; ia<NA; ia++) {
3678                ProcessRecord app = apps.valueAt(ia);
3679                if (app.persistent && !evenPersistent) {
3680                    // we don't kill persistent processes
3681                    continue;
3682                }
3683                if (app.removed) {
3684                    if (doit) {
3685                        procs.add(app);
3686                    }
3687                // If uid is specified and the uid and process name match
3688                // Or, the uid is not specified and the process name matches
3689                } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3690                            || ((app.processName.equals(packageName)
3691                                 || app.processName.startsWith(procNamePrefix))
3692                                && uid < 0))) {
3693                    if (app.setAdj >= minOomAdj) {
3694                        if (!doit) {
3695                            return true;
3696                        }
3697                        app.removed = true;
3698                        procs.add(app);
3699                    }
3700                }
3701            }
3702        }
3703
3704        int N = procs.size();
3705        for (int i=0; i<N; i++) {
3706            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3707        }
3708        return N > 0;
3709    }
3710
3711    private final boolean forceStopPackageLocked(String name, int uid,
3712            boolean callerWillRestart, boolean purgeCache, boolean doit,
3713            boolean evenPersistent, int userId) {
3714        int i;
3715        int N;
3716
3717        if (uid < 0) {
3718            try {
3719                uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
3720            } catch (RemoteException e) {
3721            }
3722        }
3723
3724        if (doit) {
3725            Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3726
3727            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3728            while (badApps.hasNext()) {
3729                SparseArray<Long> ba = badApps.next();
3730                if (ba.get(uid) != null) {
3731                    badApps.remove();
3732                }
3733            }
3734        }
3735
3736        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3737                callerWillRestart, false, doit, evenPersistent, "force stop");
3738
3739        TaskRecord lastTask = null;
3740        for (i=0; i<mMainStack.mHistory.size(); i++) {
3741            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3742            final boolean samePackage = r.packageName.equals(name);
3743            if (r.userId == userId
3744                    && (samePackage || r.task == lastTask)
3745                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3746                if (!doit) {
3747                    if (r.finishing) {
3748                        // If this activity is just finishing, then it is not
3749                        // interesting as far as something to stop.
3750                        continue;
3751                    }
3752                    return true;
3753                }
3754                didSomething = true;
3755                Slog.i(TAG, "  Force finishing activity " + r);
3756                if (samePackage) {
3757                    if (r.app != null) {
3758                        r.app.removed = true;
3759                    }
3760                    r.app = null;
3761                }
3762                lastTask = r.task;
3763                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3764                        null, "force-stop", true)) {
3765                    i--;
3766                }
3767            }
3768        }
3769
3770        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3771            if (!doit) {
3772                return true;
3773            }
3774            didSomething = true;
3775        }
3776
3777        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3778        for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
3779            if (provider.info.packageName.equals(name)
3780                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3781                if (!doit) {
3782                    return true;
3783                }
3784                didSomething = true;
3785                providers.add(provider);
3786            }
3787        }
3788
3789        N = providers.size();
3790        for (i=0; i<N; i++) {
3791            removeDyingProviderLocked(null, providers.get(i), true);
3792        }
3793
3794        if (doit) {
3795            if (purgeCache) {
3796                AttributeCache ac = AttributeCache.instance();
3797                if (ac != null) {
3798                    ac.removePackage(name);
3799                }
3800            }
3801            if (mBooted) {
3802                mMainStack.resumeTopActivityLocked(null);
3803                mMainStack.scheduleIdleLocked();
3804            }
3805        }
3806
3807        return didSomething;
3808    }
3809
3810    private final boolean removeProcessLocked(ProcessRecord app,
3811            boolean callerWillRestart, boolean allowRestart, String reason) {
3812        final String name = app.processName;
3813        final int uid = app.uid;
3814        if (DEBUG_PROCESSES) Slog.d(
3815            TAG, "Force removing proc " + app.toShortString() + " (" + name
3816            + "/" + uid + ")");
3817
3818        mProcessNames.remove(name, uid);
3819        mIsolatedProcesses.remove(app.uid);
3820        if (mHeavyWeightProcess == app) {
3821            mHeavyWeightProcess = null;
3822            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3823        }
3824        boolean needRestart = false;
3825        if (app.pid > 0 && app.pid != MY_PID) {
3826            int pid = app.pid;
3827            synchronized (mPidsSelfLocked) {
3828                mPidsSelfLocked.remove(pid);
3829                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3830            }
3831            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3832            handleAppDiedLocked(app, true, allowRestart);
3833            mLruProcesses.remove(app);
3834            Process.killProcessQuiet(pid);
3835
3836            if (app.persistent && !app.isolated) {
3837                if (!callerWillRestart) {
3838                    addAppLocked(app.info, false);
3839                } else {
3840                    needRestart = true;
3841                }
3842            }
3843        } else {
3844            mRemovedProcesses.add(app);
3845        }
3846
3847        return needRestart;
3848    }
3849
3850    private final void processStartTimedOutLocked(ProcessRecord app) {
3851        final int pid = app.pid;
3852        boolean gone = false;
3853        synchronized (mPidsSelfLocked) {
3854            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3855            if (knownApp != null && knownApp.thread == null) {
3856                mPidsSelfLocked.remove(pid);
3857                gone = true;
3858            }
3859        }
3860
3861        if (gone) {
3862            Slog.w(TAG, "Process " + app + " failed to attach");
3863            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
3864                    app.processName);
3865            mProcessNames.remove(app.processName, app.uid);
3866            mIsolatedProcesses.remove(app.uid);
3867            if (mHeavyWeightProcess == app) {
3868                mHeavyWeightProcess = null;
3869                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3870            }
3871            // Take care of any launching providers waiting for this process.
3872            checkAppInLaunchingProvidersLocked(app, true);
3873            // Take care of any services that are waiting for the process.
3874            mServices.processStartTimedOutLocked(app);
3875            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3876                    app.processName, app.setAdj, "start timeout");
3877            Process.killProcessQuiet(pid);
3878            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3879                Slog.w(TAG, "Unattached app died before backup, skipping");
3880                try {
3881                    IBackupManager bm = IBackupManager.Stub.asInterface(
3882                            ServiceManager.getService(Context.BACKUP_SERVICE));
3883                    bm.agentDisconnected(app.info.packageName);
3884                } catch (RemoteException e) {
3885                    // Can't happen; the backup manager is local
3886                }
3887            }
3888            if (isPendingBroadcastProcessLocked(pid)) {
3889                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3890                skipPendingBroadcastLocked(pid);
3891            }
3892        } else {
3893            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3894        }
3895    }
3896
3897    private final boolean attachApplicationLocked(IApplicationThread thread,
3898            int pid) {
3899
3900        // Find the application record that is being attached...  either via
3901        // the pid if we are running in multiple processes, or just pull the
3902        // next app record if we are emulating process with anonymous threads.
3903        ProcessRecord app;
3904        if (pid != MY_PID && pid >= 0) {
3905            synchronized (mPidsSelfLocked) {
3906                app = mPidsSelfLocked.get(pid);
3907            }
3908        } else {
3909            app = null;
3910        }
3911
3912        if (app == null) {
3913            Slog.w(TAG, "No pending application record for pid " + pid
3914                    + " (IApplicationThread " + thread + "); dropping process");
3915            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3916            if (pid > 0 && pid != MY_PID) {
3917                Process.killProcessQuiet(pid);
3918            } else {
3919                try {
3920                    thread.scheduleExit();
3921                } catch (Exception e) {
3922                    // Ignore exceptions.
3923                }
3924            }
3925            return false;
3926        }
3927
3928        // If this application record is still attached to a previous
3929        // process, clean it up now.
3930        if (app.thread != null) {
3931            handleAppDiedLocked(app, true, true);
3932        }
3933
3934        // Tell the process all about itself.
3935
3936        if (localLOGV) Slog.v(
3937                TAG, "Binding process pid " + pid + " to record " + app);
3938
3939        String processName = app.processName;
3940        try {
3941            AppDeathRecipient adr = new AppDeathRecipient(
3942                    app, pid, thread);
3943            thread.asBinder().linkToDeath(adr, 0);
3944            app.deathRecipient = adr;
3945        } catch (RemoteException e) {
3946            app.resetPackageList();
3947            startProcessLocked(app, "link fail", processName);
3948            return false;
3949        }
3950
3951        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
3952
3953        app.thread = thread;
3954        app.curAdj = app.setAdj = -100;
3955        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3956        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
3957        app.forcingToForeground = null;
3958        app.foregroundServices = false;
3959        app.hasShownUi = false;
3960        app.debugging = false;
3961
3962        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3963
3964        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
3965        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
3966
3967        if (!normalMode) {
3968            Slog.i(TAG, "Launching preboot mode app: " + app);
3969        }
3970
3971        if (localLOGV) Slog.v(
3972            TAG, "New app record " + app
3973            + " thread=" + thread.asBinder() + " pid=" + pid);
3974        try {
3975            int testMode = IApplicationThread.DEBUG_OFF;
3976            if (mDebugApp != null && mDebugApp.equals(processName)) {
3977                testMode = mWaitForDebugger
3978                    ? IApplicationThread.DEBUG_WAIT
3979                    : IApplicationThread.DEBUG_ON;
3980                app.debugging = true;
3981                if (mDebugTransient) {
3982                    mDebugApp = mOrigDebugApp;
3983                    mWaitForDebugger = mOrigWaitForDebugger;
3984                }
3985            }
3986            String profileFile = app.instrumentationProfileFile;
3987            ParcelFileDescriptor profileFd = null;
3988            boolean profileAutoStop = false;
3989            if (mProfileApp != null && mProfileApp.equals(processName)) {
3990                mProfileProc = app;
3991                profileFile = mProfileFile;
3992                profileFd = mProfileFd;
3993                profileAutoStop = mAutoStopProfiler;
3994            }
3995            boolean enableOpenGlTrace = false;
3996            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
3997                enableOpenGlTrace = true;
3998                mOpenGlTraceApp = null;
3999            }
4000
4001            // If the app is being launched for restore or full backup, set it up specially
4002            boolean isRestrictedBackupMode = false;
4003            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4004                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4005                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4006                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4007            }
4008
4009            ensurePackageDexOpt(app.instrumentationInfo != null
4010                    ? app.instrumentationInfo.packageName
4011                    : app.info.packageName);
4012            if (app.instrumentationClass != null) {
4013                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4014            }
4015            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4016                    + processName + " with config " + mConfiguration);
4017            ApplicationInfo appInfo = app.instrumentationInfo != null
4018                    ? app.instrumentationInfo : app.info;
4019            app.compat = compatibilityInfoForPackageLocked(appInfo);
4020            if (profileFd != null) {
4021                profileFd = profileFd.dup();
4022            }
4023            thread.bindApplication(processName, appInfo, providers,
4024                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4025                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4026                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4027                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4028                    mCoreSettingsObserver.getCoreSettingsLocked());
4029            updateLruProcessLocked(app, false, true);
4030            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4031        } catch (Exception e) {
4032            // todo: Yikes!  What should we do?  For now we will try to
4033            // start another process, but that could easily get us in
4034            // an infinite loop of restarting processes...
4035            Slog.w(TAG, "Exception thrown during bind!", e);
4036
4037            app.resetPackageList();
4038            app.unlinkDeathRecipient();
4039            startProcessLocked(app, "bind fail", processName);
4040            return false;
4041        }
4042
4043        // Remove this record from the list of starting applications.
4044        mPersistentStartingProcesses.remove(app);
4045        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4046                "Attach application locked removing on hold: " + app);
4047        mProcessesOnHold.remove(app);
4048
4049        boolean badApp = false;
4050        boolean didSomething = false;
4051
4052        // See if the top visible activity is waiting to run in this process...
4053        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4054        if (hr != null && normalMode) {
4055            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4056                    && processName.equals(hr.processName)) {
4057                try {
4058                    if (mHeadless) {
4059                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4060                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4061                        didSomething = true;
4062                    }
4063                } catch (Exception e) {
4064                    Slog.w(TAG, "Exception in new application when starting activity "
4065                          + hr.intent.getComponent().flattenToShortString(), e);
4066                    badApp = true;
4067                }
4068            } else {
4069                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4070            }
4071        }
4072
4073        // Find any services that should be running in this process...
4074        if (!badApp) {
4075            try {
4076                didSomething |= mServices.attachApplicationLocked(app, processName);
4077            } catch (Exception e) {
4078                badApp = true;
4079            }
4080        }
4081
4082        // Check if a next-broadcast receiver is in this process...
4083        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4084            try {
4085                didSomething = sendPendingBroadcastsLocked(app);
4086            } catch (Exception e) {
4087                // If the app died trying to launch the receiver we declare it 'bad'
4088                badApp = true;
4089            }
4090        }
4091
4092        // Check whether the next backup agent is in this process...
4093        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4094            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4095            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4096            try {
4097                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4098                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4099                        mBackupTarget.backupMode);
4100            } catch (Exception e) {
4101                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4102                e.printStackTrace();
4103            }
4104        }
4105
4106        if (badApp) {
4107            // todo: Also need to kill application to deal with all
4108            // kinds of exceptions.
4109            handleAppDiedLocked(app, false, true);
4110            return false;
4111        }
4112
4113        if (!didSomething) {
4114            updateOomAdjLocked();
4115        }
4116
4117        return true;
4118    }
4119
4120    public final void attachApplication(IApplicationThread thread) {
4121        synchronized (this) {
4122            int callingPid = Binder.getCallingPid();
4123            final long origId = Binder.clearCallingIdentity();
4124            attachApplicationLocked(thread, callingPid);
4125            Binder.restoreCallingIdentity(origId);
4126        }
4127    }
4128
4129    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4130        final long origId = Binder.clearCallingIdentity();
4131        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4132        if (stopProfiling) {
4133            synchronized (this) {
4134                if (mProfileProc == r.app) {
4135                    if (mProfileFd != null) {
4136                        try {
4137                            mProfileFd.close();
4138                        } catch (IOException e) {
4139                        }
4140                        clearProfilerLocked();
4141                    }
4142                }
4143            }
4144        }
4145        Binder.restoreCallingIdentity(origId);
4146    }
4147
4148    void enableScreenAfterBoot() {
4149        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4150                SystemClock.uptimeMillis());
4151        mWindowManager.enableScreenAfterBoot();
4152
4153        synchronized (this) {
4154            updateEventDispatchingLocked();
4155        }
4156    }
4157
4158    public void showBootMessage(final CharSequence msg, final boolean always) {
4159        enforceNotIsolatedCaller("showBootMessage");
4160        mWindowManager.showBootMessage(msg, always);
4161    }
4162
4163    public void dismissKeyguardOnNextActivity() {
4164        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4165        final long token = Binder.clearCallingIdentity();
4166        try {
4167            synchronized (this) {
4168                if (mLockScreenShown) {
4169                    mLockScreenShown = false;
4170                    comeOutOfSleepIfNeededLocked();
4171                }
4172                mMainStack.dismissKeyguardOnNextActivityLocked();
4173            }
4174        } finally {
4175            Binder.restoreCallingIdentity(token);
4176        }
4177    }
4178
4179    final void finishBooting() {
4180        IntentFilter pkgFilter = new IntentFilter();
4181        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4182        pkgFilter.addDataScheme("package");
4183        mContext.registerReceiver(new BroadcastReceiver() {
4184            @Override
4185            public void onReceive(Context context, Intent intent) {
4186                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4187                if (pkgs != null) {
4188                    for (String pkg : pkgs) {
4189                        synchronized (ActivityManagerService.this) {
4190                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4191                                setResultCode(Activity.RESULT_OK);
4192                                return;
4193                            }
4194                        }
4195                    }
4196                }
4197            }
4198        }, pkgFilter);
4199
4200        IntentFilter userFilter = new IntentFilter();
4201        userFilter.addAction(Intent.ACTION_USER_REMOVED);
4202        mContext.registerReceiver(new BroadcastReceiver() {
4203            @Override
4204            public void onReceive(Context context, Intent intent) {
4205                onUserRemoved(intent);
4206            }
4207        }, userFilter);
4208
4209        synchronized (this) {
4210            // Ensure that any processes we had put on hold are now started
4211            // up.
4212            final int NP = mProcessesOnHold.size();
4213            if (NP > 0) {
4214                ArrayList<ProcessRecord> procs =
4215                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4216                for (int ip=0; ip<NP; ip++) {
4217                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4218                            + procs.get(ip));
4219                    startProcessLocked(procs.get(ip), "on-hold", null);
4220                }
4221            }
4222
4223            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4224                // Start looking for apps that are abusing wake locks.
4225                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4226                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4227                // Tell anyone interested that we are done booting!
4228                SystemProperties.set("sys.boot_completed", "1");
4229                SystemProperties.set("dev.bootcomplete", "1");
4230                List<UserInfo> users = getUserManager().getUsers();
4231                for (UserInfo user : users) {
4232                    broadcastIntentLocked(null, null,
4233                            new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4234                            null, null, 0, null, null,
4235                            android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4236                            false, false, MY_PID, Process.SYSTEM_UID, user.id);
4237                }
4238            }
4239        }
4240    }
4241
4242    final void ensureBootCompleted() {
4243        boolean booting;
4244        boolean enableScreen;
4245        synchronized (this) {
4246            booting = mBooting;
4247            mBooting = false;
4248            enableScreen = !mBooted;
4249            mBooted = true;
4250        }
4251
4252        if (booting) {
4253            finishBooting();
4254        }
4255
4256        if (enableScreen) {
4257            enableScreenAfterBoot();
4258        }
4259    }
4260
4261    public final void activityPaused(IBinder token) {
4262        final long origId = Binder.clearCallingIdentity();
4263        mMainStack.activityPaused(token, false);
4264        Binder.restoreCallingIdentity(origId);
4265    }
4266
4267    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4268            CharSequence description) {
4269        if (localLOGV) Slog.v(
4270            TAG, "Activity stopped: token=" + token);
4271
4272        // Refuse possible leaked file descriptors
4273        if (icicle != null && icicle.hasFileDescriptors()) {
4274            throw new IllegalArgumentException("File descriptors passed in Bundle");
4275        }
4276
4277        ActivityRecord r = null;
4278
4279        final long origId = Binder.clearCallingIdentity();
4280
4281        synchronized (this) {
4282            r = mMainStack.isInStackLocked(token);
4283            if (r != null) {
4284                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4285            }
4286        }
4287
4288        if (r != null) {
4289            sendPendingThumbnail(r, null, null, null, false);
4290        }
4291
4292        trimApplications();
4293
4294        Binder.restoreCallingIdentity(origId);
4295    }
4296
4297    public final void activityDestroyed(IBinder token) {
4298        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4299        mMainStack.activityDestroyed(token);
4300    }
4301
4302    public String getCallingPackage(IBinder token) {
4303        synchronized (this) {
4304            ActivityRecord r = getCallingRecordLocked(token);
4305            return r != null && r.app != null ? r.info.packageName : null;
4306        }
4307    }
4308
4309    public ComponentName getCallingActivity(IBinder token) {
4310        synchronized (this) {
4311            ActivityRecord r = getCallingRecordLocked(token);
4312            return r != null ? r.intent.getComponent() : null;
4313        }
4314    }
4315
4316    private ActivityRecord getCallingRecordLocked(IBinder token) {
4317        ActivityRecord r = mMainStack.isInStackLocked(token);
4318        if (r == null) {
4319            return null;
4320        }
4321        return r.resultTo;
4322    }
4323
4324    public ComponentName getActivityClassForToken(IBinder token) {
4325        synchronized(this) {
4326            ActivityRecord r = mMainStack.isInStackLocked(token);
4327            if (r == null) {
4328                return null;
4329            }
4330            return r.intent.getComponent();
4331        }
4332    }
4333
4334    public String getPackageForToken(IBinder token) {
4335        synchronized(this) {
4336            ActivityRecord r = mMainStack.isInStackLocked(token);
4337            if (r == null) {
4338                return null;
4339            }
4340            return r.packageName;
4341        }
4342    }
4343
4344    public IIntentSender getIntentSender(int type,
4345            String packageName, IBinder token, String resultWho,
4346            int requestCode, Intent[] intents, String[] resolvedTypes,
4347            int flags, Bundle options) {
4348        enforceNotIsolatedCaller("getIntentSender");
4349        // Refuse possible leaked file descriptors
4350        if (intents != null) {
4351            if (intents.length < 1) {
4352                throw new IllegalArgumentException("Intents array length must be >= 1");
4353            }
4354            for (int i=0; i<intents.length; i++) {
4355                Intent intent = intents[i];
4356                if (intent != null) {
4357                    if (intent.hasFileDescriptors()) {
4358                        throw new IllegalArgumentException("File descriptors passed in Intent");
4359                    }
4360                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4361                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4362                        throw new IllegalArgumentException(
4363                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4364                    }
4365                    intents[i] = new Intent(intent);
4366                }
4367            }
4368            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4369                throw new IllegalArgumentException(
4370                        "Intent array length does not match resolvedTypes length");
4371            }
4372        }
4373        if (options != null) {
4374            if (options.hasFileDescriptors()) {
4375                throw new IllegalArgumentException("File descriptors passed in options");
4376            }
4377        }
4378
4379        synchronized(this) {
4380            int callingUid = Binder.getCallingUid();
4381            try {
4382                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4383                    int uid = AppGlobals.getPackageManager()
4384                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4385                    if (!UserHandle.isSameApp(callingUid, uid)) {
4386                        String msg = "Permission Denial: getIntentSender() from pid="
4387                            + Binder.getCallingPid()
4388                            + ", uid=" + Binder.getCallingUid()
4389                            + ", (need uid=" + uid + ")"
4390                            + " is not allowed to send as package " + packageName;
4391                        Slog.w(TAG, msg);
4392                        throw new SecurityException(msg);
4393                    }
4394                }
4395
4396                if (DEBUG_MU)
4397                    Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
4398                            + Binder.getOrigCallingUid());
4399                return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
4400                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4401
4402            } catch (RemoteException e) {
4403                throw new SecurityException(e);
4404            }
4405        }
4406    }
4407
4408    IIntentSender getIntentSenderLocked(int type,
4409            String packageName, int callingUid, IBinder token, String resultWho,
4410            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4411            Bundle options) {
4412        if (DEBUG_MU)
4413            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4414        ActivityRecord activity = null;
4415        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4416            activity = mMainStack.isInStackLocked(token);
4417            if (activity == null) {
4418                return null;
4419            }
4420            if (activity.finishing) {
4421                return null;
4422            }
4423        }
4424
4425        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4426        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4427        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4428        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4429                |PendingIntent.FLAG_UPDATE_CURRENT);
4430
4431        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4432                type, packageName, activity, resultWho,
4433                requestCode, intents, resolvedTypes, flags, options);
4434        WeakReference<PendingIntentRecord> ref;
4435        ref = mIntentSenderRecords.get(key);
4436        PendingIntentRecord rec = ref != null ? ref.get() : null;
4437        if (rec != null) {
4438            if (!cancelCurrent) {
4439                if (updateCurrent) {
4440                    if (rec.key.requestIntent != null) {
4441                        rec.key.requestIntent.replaceExtras(intents != null ?
4442                                intents[intents.length - 1] : null);
4443                    }
4444                    if (intents != null) {
4445                        intents[intents.length-1] = rec.key.requestIntent;
4446                        rec.key.allIntents = intents;
4447                        rec.key.allResolvedTypes = resolvedTypes;
4448                    } else {
4449                        rec.key.allIntents = null;
4450                        rec.key.allResolvedTypes = null;
4451                    }
4452                }
4453                return rec;
4454            }
4455            rec.canceled = true;
4456            mIntentSenderRecords.remove(key);
4457        }
4458        if (noCreate) {
4459            return rec;
4460        }
4461        rec = new PendingIntentRecord(this, key, callingUid);
4462        mIntentSenderRecords.put(key, rec.ref);
4463        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4464            if (activity.pendingResults == null) {
4465                activity.pendingResults
4466                        = new HashSet<WeakReference<PendingIntentRecord>>();
4467            }
4468            activity.pendingResults.add(rec.ref);
4469        }
4470        return rec;
4471    }
4472
4473    public void cancelIntentSender(IIntentSender sender) {
4474        if (!(sender instanceof PendingIntentRecord)) {
4475            return;
4476        }
4477        synchronized(this) {
4478            PendingIntentRecord rec = (PendingIntentRecord)sender;
4479            try {
4480                int uid = AppGlobals.getPackageManager()
4481                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4482                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4483                    String msg = "Permission Denial: cancelIntentSender() from pid="
4484                        + Binder.getCallingPid()
4485                        + ", uid=" + Binder.getCallingUid()
4486                        + " is not allowed to cancel packges "
4487                        + rec.key.packageName;
4488                    Slog.w(TAG, msg);
4489                    throw new SecurityException(msg);
4490                }
4491            } catch (RemoteException e) {
4492                throw new SecurityException(e);
4493            }
4494            cancelIntentSenderLocked(rec, true);
4495        }
4496    }
4497
4498    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4499        rec.canceled = true;
4500        mIntentSenderRecords.remove(rec.key);
4501        if (cleanActivity && rec.key.activity != null) {
4502            rec.key.activity.pendingResults.remove(rec.ref);
4503        }
4504    }
4505
4506    public String getPackageForIntentSender(IIntentSender pendingResult) {
4507        if (!(pendingResult instanceof PendingIntentRecord)) {
4508            return null;
4509        }
4510        try {
4511            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4512            return res.key.packageName;
4513        } catch (ClassCastException e) {
4514        }
4515        return null;
4516    }
4517
4518    public int getUidForIntentSender(IIntentSender sender) {
4519        if (sender instanceof PendingIntentRecord) {
4520            try {
4521                PendingIntentRecord res = (PendingIntentRecord)sender;
4522                return res.uid;
4523            } catch (ClassCastException e) {
4524            }
4525        }
4526        return -1;
4527    }
4528
4529    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4530        if (!(pendingResult instanceof PendingIntentRecord)) {
4531            return false;
4532        }
4533        try {
4534            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4535            if (res.key.allIntents == null) {
4536                return false;
4537            }
4538            for (int i=0; i<res.key.allIntents.length; i++) {
4539                Intent intent = res.key.allIntents[i];
4540                if (intent.getPackage() != null && intent.getComponent() != null) {
4541                    return false;
4542                }
4543            }
4544            return true;
4545        } catch (ClassCastException e) {
4546        }
4547        return false;
4548    }
4549
4550    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4551        if (!(pendingResult instanceof PendingIntentRecord)) {
4552            return false;
4553        }
4554        try {
4555            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4556            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4557                return true;
4558            }
4559            return false;
4560        } catch (ClassCastException e) {
4561        }
4562        return false;
4563    }
4564
4565    public void setProcessLimit(int max) {
4566        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4567                "setProcessLimit()");
4568        synchronized (this) {
4569            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4570            mProcessLimitOverride = max;
4571        }
4572        trimApplications();
4573    }
4574
4575    public int getProcessLimit() {
4576        synchronized (this) {
4577            return mProcessLimitOverride;
4578        }
4579    }
4580
4581    void foregroundTokenDied(ForegroundToken token) {
4582        synchronized (ActivityManagerService.this) {
4583            synchronized (mPidsSelfLocked) {
4584                ForegroundToken cur
4585                    = mForegroundProcesses.get(token.pid);
4586                if (cur != token) {
4587                    return;
4588                }
4589                mForegroundProcesses.remove(token.pid);
4590                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4591                if (pr == null) {
4592                    return;
4593                }
4594                pr.forcingToForeground = null;
4595                pr.foregroundServices = false;
4596            }
4597            updateOomAdjLocked();
4598        }
4599    }
4600
4601    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4602        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4603                "setProcessForeground()");
4604        synchronized(this) {
4605            boolean changed = false;
4606
4607            synchronized (mPidsSelfLocked) {
4608                ProcessRecord pr = mPidsSelfLocked.get(pid);
4609                if (pr == null && isForeground) {
4610                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4611                    return;
4612                }
4613                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4614                if (oldToken != null) {
4615                    oldToken.token.unlinkToDeath(oldToken, 0);
4616                    mForegroundProcesses.remove(pid);
4617                    if (pr != null) {
4618                        pr.forcingToForeground = null;
4619                    }
4620                    changed = true;
4621                }
4622                if (isForeground && token != null) {
4623                    ForegroundToken newToken = new ForegroundToken() {
4624                        public void binderDied() {
4625                            foregroundTokenDied(this);
4626                        }
4627                    };
4628                    newToken.pid = pid;
4629                    newToken.token = token;
4630                    try {
4631                        token.linkToDeath(newToken, 0);
4632                        mForegroundProcesses.put(pid, newToken);
4633                        pr.forcingToForeground = token;
4634                        changed = true;
4635                    } catch (RemoteException e) {
4636                        // If the process died while doing this, we will later
4637                        // do the cleanup with the process death link.
4638                    }
4639                }
4640            }
4641
4642            if (changed) {
4643                updateOomAdjLocked();
4644            }
4645        }
4646    }
4647
4648    // =========================================================
4649    // PERMISSIONS
4650    // =========================================================
4651
4652    static class PermissionController extends IPermissionController.Stub {
4653        ActivityManagerService mActivityManagerService;
4654        PermissionController(ActivityManagerService activityManagerService) {
4655            mActivityManagerService = activityManagerService;
4656        }
4657
4658        public boolean checkPermission(String permission, int pid, int uid) {
4659            return mActivityManagerService.checkPermission(permission, pid,
4660                    uid) == PackageManager.PERMISSION_GRANTED;
4661        }
4662    }
4663
4664    /**
4665     * This can be called with or without the global lock held.
4666     */
4667    int checkComponentPermission(String permission, int pid, int uid,
4668            int owningUid, boolean exported) {
4669        // We might be performing an operation on behalf of an indirect binder
4670        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4671        // client identity accordingly before proceeding.
4672        Identity tlsIdentity = sCallerIdentity.get();
4673        if (tlsIdentity != null) {
4674            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4675                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4676            uid = tlsIdentity.uid;
4677            pid = tlsIdentity.pid;
4678        }
4679
4680        if (pid == MY_PID) {
4681            return PackageManager.PERMISSION_GRANTED;
4682        }
4683
4684        return ActivityManager.checkComponentPermission(permission, uid,
4685                owningUid, exported);
4686    }
4687
4688    /**
4689     * As the only public entry point for permissions checking, this method
4690     * can enforce the semantic that requesting a check on a null global
4691     * permission is automatically denied.  (Internally a null permission
4692     * string is used when calling {@link #checkComponentPermission} in cases
4693     * when only uid-based security is needed.)
4694     *
4695     * This can be called with or without the global lock held.
4696     */
4697    public int checkPermission(String permission, int pid, int uid) {
4698        if (permission == null) {
4699            return PackageManager.PERMISSION_DENIED;
4700        }
4701        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4702    }
4703
4704    /**
4705     * Binder IPC calls go through the public entry point.
4706     * This can be called with or without the global lock held.
4707     */
4708    int checkCallingPermission(String permission) {
4709        return checkPermission(permission,
4710                Binder.getCallingPid(),
4711                UserHandle.getAppId(Binder.getCallingUid()));
4712    }
4713
4714    /**
4715     * This can be called with or without the global lock held.
4716     */
4717    void enforceCallingPermission(String permission, String func) {
4718        if (checkCallingPermission(permission)
4719                == PackageManager.PERMISSION_GRANTED) {
4720            return;
4721        }
4722
4723        String msg = "Permission Denial: " + func + " from pid="
4724                + Binder.getCallingPid()
4725                + ", uid=" + Binder.getCallingUid()
4726                + " requires " + permission;
4727        Slog.w(TAG, msg);
4728        throw new SecurityException(msg);
4729    }
4730
4731    /**
4732     * Determine if UID is holding permissions required to access {@link Uri} in
4733     * the given {@link ProviderInfo}. Final permission checking is always done
4734     * in {@link ContentProvider}.
4735     */
4736    private final boolean checkHoldingPermissionsLocked(
4737            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4738        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4739                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4740
4741        if (pi.applicationInfo.uid == uid) {
4742            return true;
4743        } else if (!pi.exported) {
4744            return false;
4745        }
4746
4747        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4748        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4749        try {
4750            // check if target holds top-level <provider> permissions
4751            if (!readMet && pi.readPermission != null
4752                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4753                readMet = true;
4754            }
4755            if (!writeMet && pi.writePermission != null
4756                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4757                writeMet = true;
4758            }
4759
4760            // track if unprotected read/write is allowed; any denied
4761            // <path-permission> below removes this ability
4762            boolean allowDefaultRead = pi.readPermission == null;
4763            boolean allowDefaultWrite = pi.writePermission == null;
4764
4765            // check if target holds any <path-permission> that match uri
4766            final PathPermission[] pps = pi.pathPermissions;
4767            if (pps != null) {
4768                final String path = uri.getPath();
4769                int i = pps.length;
4770                while (i > 0 && (!readMet || !writeMet)) {
4771                    i--;
4772                    PathPermission pp = pps[i];
4773                    if (pp.match(path)) {
4774                        if (!readMet) {
4775                            final String pprperm = pp.getReadPermission();
4776                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4777                                    + pprperm + " for " + pp.getPath()
4778                                    + ": match=" + pp.match(path)
4779                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4780                            if (pprperm != null) {
4781                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4782                                    readMet = true;
4783                                } else {
4784                                    allowDefaultRead = false;
4785                                }
4786                            }
4787                        }
4788                        if (!writeMet) {
4789                            final String ppwperm = pp.getWritePermission();
4790                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4791                                    + ppwperm + " for " + pp.getPath()
4792                                    + ": match=" + pp.match(path)
4793                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4794                            if (ppwperm != null) {
4795                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4796                                    writeMet = true;
4797                                } else {
4798                                    allowDefaultWrite = false;
4799                                }
4800                            }
4801                        }
4802                    }
4803                }
4804            }
4805
4806            // grant unprotected <provider> read/write, if not blocked by
4807            // <path-permission> above
4808            if (allowDefaultRead) readMet = true;
4809            if (allowDefaultWrite) writeMet = true;
4810
4811        } catch (RemoteException e) {
4812            return false;
4813        }
4814
4815        return readMet && writeMet;
4816    }
4817
4818    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4819            int modeFlags) {
4820        // Root gets to do everything.
4821        if (uid == 0) {
4822            return true;
4823        }
4824        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4825        if (perms == null) return false;
4826        UriPermission perm = perms.get(uri);
4827        if (perm == null) return false;
4828        return (modeFlags&perm.modeFlags) == modeFlags;
4829    }
4830
4831    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4832        enforceNotIsolatedCaller("checkUriPermission");
4833
4834        // Another redirected-binder-call permissions check as in
4835        // {@link checkComponentPermission}.
4836        Identity tlsIdentity = sCallerIdentity.get();
4837        if (tlsIdentity != null) {
4838            uid = tlsIdentity.uid;
4839            pid = tlsIdentity.pid;
4840        }
4841
4842        uid = UserHandle.getAppId(uid);
4843        // Our own process gets to do everything.
4844        if (pid == MY_PID) {
4845            return PackageManager.PERMISSION_GRANTED;
4846        }
4847        synchronized(this) {
4848            return checkUriPermissionLocked(uri, uid, modeFlags)
4849                    ? PackageManager.PERMISSION_GRANTED
4850                    : PackageManager.PERMISSION_DENIED;
4851        }
4852    }
4853
4854    /**
4855     * Check if the targetPkg can be granted permission to access uri by
4856     * the callingUid using the given modeFlags.  Throws a security exception
4857     * if callingUid is not allowed to do this.  Returns the uid of the target
4858     * if the URI permission grant should be performed; returns -1 if it is not
4859     * needed (for example targetPkg already has permission to access the URI).
4860     * If you already know the uid of the target, you can supply it in
4861     * lastTargetUid else set that to -1.
4862     */
4863    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4864            Uri uri, int modeFlags, int lastTargetUid) {
4865        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4866                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4867        if (modeFlags == 0) {
4868            return -1;
4869        }
4870
4871        if (targetPkg != null) {
4872            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4873                    "Checking grant " + targetPkg + " permission to " + uri);
4874        }
4875
4876        final IPackageManager pm = AppGlobals.getPackageManager();
4877
4878        // If this is not a content: uri, we can't do anything with it.
4879        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4880            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4881                    "Can't grant URI permission for non-content URI: " + uri);
4882            return -1;
4883        }
4884
4885        String name = uri.getAuthority();
4886        ProviderInfo pi = null;
4887        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
4888                UserHandle.getUserId(callingUid));
4889        if (cpr != null) {
4890            pi = cpr.info;
4891        } else {
4892            try {
4893                pi = pm.resolveContentProvider(name,
4894                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid));
4895            } catch (RemoteException ex) {
4896            }
4897        }
4898        if (pi == null) {
4899            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
4900            return -1;
4901        }
4902
4903        int targetUid = lastTargetUid;
4904        if (targetUid < 0 && targetPkg != null) {
4905            try {
4906                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
4907                if (targetUid < 0) {
4908                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4909                            "Can't grant URI permission no uid for: " + targetPkg);
4910                    return -1;
4911                }
4912            } catch (RemoteException ex) {
4913                return -1;
4914            }
4915        }
4916
4917        if (targetUid >= 0) {
4918            // First...  does the target actually need this permission?
4919            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4920                // No need to grant the target this permission.
4921                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4922                        "Target " + targetPkg + " already has full permission to " + uri);
4923                return -1;
4924            }
4925        } else {
4926            // First...  there is no target package, so can anyone access it?
4927            boolean allowed = pi.exported;
4928            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4929                if (pi.readPermission != null) {
4930                    allowed = false;
4931                }
4932            }
4933            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4934                if (pi.writePermission != null) {
4935                    allowed = false;
4936                }
4937            }
4938            if (allowed) {
4939                return -1;
4940            }
4941        }
4942
4943        // Second...  is the provider allowing granting of URI permissions?
4944        if (!pi.grantUriPermissions) {
4945            throw new SecurityException("Provider " + pi.packageName
4946                    + "/" + pi.name
4947                    + " does not allow granting of Uri permissions (uri "
4948                    + uri + ")");
4949        }
4950        if (pi.uriPermissionPatterns != null) {
4951            final int N = pi.uriPermissionPatterns.length;
4952            boolean allowed = false;
4953            for (int i=0; i<N; i++) {
4954                if (pi.uriPermissionPatterns[i] != null
4955                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4956                    allowed = true;
4957                    break;
4958                }
4959            }
4960            if (!allowed) {
4961                throw new SecurityException("Provider " + pi.packageName
4962                        + "/" + pi.name
4963                        + " does not allow granting of permission to path of Uri "
4964                        + uri);
4965            }
4966        }
4967
4968        // Third...  does the caller itself have permission to access
4969        // this uri?
4970        if (callingUid != Process.myUid()) {
4971            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4972                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4973                    throw new SecurityException("Uid " + callingUid
4974                            + " does not have permission to uri " + uri);
4975                }
4976            }
4977        }
4978
4979        return targetUid;
4980    }
4981
4982    public int checkGrantUriPermission(int callingUid, String targetPkg,
4983            Uri uri, int modeFlags) {
4984        enforceNotIsolatedCaller("checkGrantUriPermission");
4985        synchronized(this) {
4986            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
4987        }
4988    }
4989
4990    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4991            Uri uri, int modeFlags, UriPermissionOwner owner) {
4992        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4993                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4994        if (modeFlags == 0) {
4995            return;
4996        }
4997
4998        // So here we are: the caller has the assumed permission
4999        // to the uri, and the target doesn't.  Let's now give this to
5000        // the target.
5001
5002        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5003                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5004
5005        HashMap<Uri, UriPermission> targetUris
5006                = mGrantedUriPermissions.get(targetUid);
5007        if (targetUris == null) {
5008            targetUris = new HashMap<Uri, UriPermission>();
5009            mGrantedUriPermissions.put(targetUid, targetUris);
5010        }
5011
5012        UriPermission perm = targetUris.get(uri);
5013        if (perm == null) {
5014            perm = new UriPermission(targetUid, uri);
5015            targetUris.put(uri, perm);
5016        }
5017
5018        perm.modeFlags |= modeFlags;
5019        if (owner == null) {
5020            perm.globalModeFlags |= modeFlags;
5021        } else {
5022            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5023                 perm.readOwners.add(owner);
5024                 owner.addReadPermission(perm);
5025            }
5026            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5027                 perm.writeOwners.add(owner);
5028                 owner.addWritePermission(perm);
5029            }
5030        }
5031    }
5032
5033    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5034            int modeFlags, UriPermissionOwner owner) {
5035        if (targetPkg == null) {
5036            throw new NullPointerException("targetPkg");
5037        }
5038
5039        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5040        if (targetUid < 0) {
5041            return;
5042        }
5043
5044        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5045    }
5046
5047    static class NeededUriGrants extends ArrayList<Uri> {
5048        final String targetPkg;
5049        final int targetUid;
5050        final int flags;
5051
5052        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5053            targetPkg = _targetPkg;
5054            targetUid = _targetUid;
5055            flags = _flags;
5056        }
5057    }
5058
5059    /**
5060     * Like checkGrantUriPermissionLocked, but takes an Intent.
5061     */
5062    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5063            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5064        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5065                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5066                + " clip=" + (intent != null ? intent.getClipData() : null)
5067                + " from " + intent + "; flags=0x"
5068                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5069
5070        if (targetPkg == null) {
5071            throw new NullPointerException("targetPkg");
5072        }
5073
5074        if (intent == null) {
5075            return null;
5076        }
5077        Uri data = intent.getData();
5078        ClipData clip = intent.getClipData();
5079        if (data == null && clip == null) {
5080            return null;
5081        }
5082        if (data != null) {
5083            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5084                mode, needed != null ? needed.targetUid : -1);
5085            if (target > 0) {
5086                if (needed == null) {
5087                    needed = new NeededUriGrants(targetPkg, target, mode);
5088                }
5089                needed.add(data);
5090            }
5091        }
5092        if (clip != null) {
5093            for (int i=0; i<clip.getItemCount(); i++) {
5094                Uri uri = clip.getItemAt(i).getUri();
5095                if (uri != null) {
5096                    int target = -1;
5097                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5098                            mode, needed != null ? needed.targetUid : -1);
5099                    if (target > 0) {
5100                        if (needed == null) {
5101                            needed = new NeededUriGrants(targetPkg, target, mode);
5102                        }
5103                        needed.add(uri);
5104                    }
5105                } else {
5106                    Intent clipIntent = clip.getItemAt(i).getIntent();
5107                    if (clipIntent != null) {
5108                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5109                                callingUid, targetPkg, clipIntent, mode, needed);
5110                        if (newNeeded != null) {
5111                            needed = newNeeded;
5112                        }
5113                    }
5114                }
5115            }
5116        }
5117
5118        return needed;
5119    }
5120
5121    /**
5122     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5123     */
5124    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5125            UriPermissionOwner owner) {
5126        if (needed != null) {
5127            for (int i=0; i<needed.size(); i++) {
5128                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5129                        needed.get(i), needed.flags, owner);
5130            }
5131        }
5132    }
5133
5134    void grantUriPermissionFromIntentLocked(int callingUid,
5135            String targetPkg, Intent intent, UriPermissionOwner owner) {
5136        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5137                intent, intent != null ? intent.getFlags() : 0, null);
5138        if (needed == null) {
5139            return;
5140        }
5141
5142        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5143    }
5144
5145    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5146            Uri uri, int modeFlags) {
5147        enforceNotIsolatedCaller("grantUriPermission");
5148        synchronized(this) {
5149            final ProcessRecord r = getRecordForAppLocked(caller);
5150            if (r == null) {
5151                throw new SecurityException("Unable to find app for caller "
5152                        + caller
5153                        + " when granting permission to uri " + uri);
5154            }
5155            if (targetPkg == null) {
5156                throw new IllegalArgumentException("null target");
5157            }
5158            if (uri == null) {
5159                throw new IllegalArgumentException("null uri");
5160            }
5161
5162            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5163                    null);
5164        }
5165    }
5166
5167    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5168        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5169                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5170            HashMap<Uri, UriPermission> perms
5171                    = mGrantedUriPermissions.get(perm.uid);
5172            if (perms != null) {
5173                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5174                        "Removing " + perm.uid + " permission to " + perm.uri);
5175                perms.remove(perm.uri);
5176                if (perms.size() == 0) {
5177                    mGrantedUriPermissions.remove(perm.uid);
5178                }
5179            }
5180        }
5181    }
5182
5183    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5184            int modeFlags) {
5185        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5186                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5187        if (modeFlags == 0) {
5188            return;
5189        }
5190
5191        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5192                "Revoking all granted permissions to " + uri);
5193
5194        final IPackageManager pm = AppGlobals.getPackageManager();
5195
5196        final String authority = uri.getAuthority();
5197        ProviderInfo pi = null;
5198        int userId = UserHandle.getUserId(callingUid);
5199        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5200        if (cpr != null) {
5201            pi = cpr.info;
5202        } else {
5203            try {
5204                pi = pm.resolveContentProvider(authority,
5205                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5206            } catch (RemoteException ex) {
5207            }
5208        }
5209        if (pi == null) {
5210            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5211            return;
5212        }
5213
5214        // Does the caller have this permission on the URI?
5215        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5216            // Right now, if you are not the original owner of the permission,
5217            // you are not allowed to revoke it.
5218            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5219                throw new SecurityException("Uid " + callingUid
5220                        + " does not have permission to uri " + uri);
5221            //}
5222        }
5223
5224        // Go through all of the permissions and remove any that match.
5225        final List<String> SEGMENTS = uri.getPathSegments();
5226        if (SEGMENTS != null) {
5227            final int NS = SEGMENTS.size();
5228            int N = mGrantedUriPermissions.size();
5229            for (int i=0; i<N; i++) {
5230                HashMap<Uri, UriPermission> perms
5231                        = mGrantedUriPermissions.valueAt(i);
5232                Iterator<UriPermission> it = perms.values().iterator();
5233            toploop:
5234                while (it.hasNext()) {
5235                    UriPermission perm = it.next();
5236                    Uri targetUri = perm.uri;
5237                    if (!authority.equals(targetUri.getAuthority())) {
5238                        continue;
5239                    }
5240                    List<String> targetSegments = targetUri.getPathSegments();
5241                    if (targetSegments == null) {
5242                        continue;
5243                    }
5244                    if (targetSegments.size() < NS) {
5245                        continue;
5246                    }
5247                    for (int j=0; j<NS; j++) {
5248                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5249                            continue toploop;
5250                        }
5251                    }
5252                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5253                            "Revoking " + perm.uid + " permission to " + perm.uri);
5254                    perm.clearModes(modeFlags);
5255                    if (perm.modeFlags == 0) {
5256                        it.remove();
5257                    }
5258                }
5259                if (perms.size() == 0) {
5260                    mGrantedUriPermissions.remove(
5261                            mGrantedUriPermissions.keyAt(i));
5262                    N--;
5263                    i--;
5264                }
5265            }
5266        }
5267    }
5268
5269    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5270            int modeFlags) {
5271        enforceNotIsolatedCaller("revokeUriPermission");
5272        synchronized(this) {
5273            final ProcessRecord r = getRecordForAppLocked(caller);
5274            if (r == null) {
5275                throw new SecurityException("Unable to find app for caller "
5276                        + caller
5277                        + " when revoking permission to uri " + uri);
5278            }
5279            if (uri == null) {
5280                Slog.w(TAG, "revokeUriPermission: null uri");
5281                return;
5282            }
5283
5284            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5285                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5286            if (modeFlags == 0) {
5287                return;
5288            }
5289
5290            final IPackageManager pm = AppGlobals.getPackageManager();
5291
5292            final String authority = uri.getAuthority();
5293            ProviderInfo pi = null;
5294            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5295            if (cpr != null) {
5296                pi = cpr.info;
5297            } else {
5298                try {
5299                    pi = pm.resolveContentProvider(authority,
5300                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5301                } catch (RemoteException ex) {
5302                }
5303            }
5304            if (pi == null) {
5305                Slog.w(TAG, "No content provider found for permission revoke: "
5306                        + uri.toSafeString());
5307                return;
5308            }
5309
5310            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5311        }
5312    }
5313
5314    @Override
5315    public IBinder newUriPermissionOwner(String name) {
5316        enforceNotIsolatedCaller("newUriPermissionOwner");
5317        synchronized(this) {
5318            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5319            return owner.getExternalTokenLocked();
5320        }
5321    }
5322
5323    @Override
5324    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5325            Uri uri, int modeFlags) {
5326        synchronized(this) {
5327            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5328            if (owner == null) {
5329                throw new IllegalArgumentException("Unknown owner: " + token);
5330            }
5331            if (fromUid != Binder.getCallingUid()) {
5332                if (Binder.getCallingUid() != Process.myUid()) {
5333                    // Only system code can grant URI permissions on behalf
5334                    // of other users.
5335                    throw new SecurityException("nice try");
5336                }
5337            }
5338            if (targetPkg == null) {
5339                throw new IllegalArgumentException("null target");
5340            }
5341            if (uri == null) {
5342                throw new IllegalArgumentException("null uri");
5343            }
5344
5345            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5346        }
5347    }
5348
5349    @Override
5350    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5351        synchronized(this) {
5352            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5353            if (owner == null) {
5354                throw new IllegalArgumentException("Unknown owner: " + token);
5355            }
5356
5357            if (uri == null) {
5358                owner.removeUriPermissionsLocked(mode);
5359            } else {
5360                owner.removeUriPermissionLocked(uri, mode);
5361            }
5362        }
5363    }
5364
5365    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5366        synchronized (this) {
5367            ProcessRecord app =
5368                who != null ? getRecordForAppLocked(who) : null;
5369            if (app == null) return;
5370
5371            Message msg = Message.obtain();
5372            msg.what = WAIT_FOR_DEBUGGER_MSG;
5373            msg.obj = app;
5374            msg.arg1 = waiting ? 1 : 0;
5375            mHandler.sendMessage(msg);
5376        }
5377    }
5378
5379    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5380        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5381        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5382        outInfo.availMem = Process.getFreeMemory();
5383        outInfo.totalMem = Process.getTotalMemory();
5384        outInfo.threshold = homeAppMem;
5385        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5386        outInfo.hiddenAppThreshold = hiddenAppMem;
5387        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5388                ProcessList.SERVICE_ADJ);
5389        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5390                ProcessList.VISIBLE_APP_ADJ);
5391        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5392                ProcessList.FOREGROUND_APP_ADJ);
5393    }
5394
5395    // =========================================================
5396    // TASK MANAGEMENT
5397    // =========================================================
5398
5399    public List getTasks(int maxNum, int flags,
5400                         IThumbnailReceiver receiver) {
5401        ArrayList list = new ArrayList();
5402
5403        PendingThumbnailsRecord pending = null;
5404        IApplicationThread topThumbnail = null;
5405        ActivityRecord topRecord = null;
5406
5407        synchronized(this) {
5408            if (localLOGV) Slog.v(
5409                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5410                + ", receiver=" + receiver);
5411
5412            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5413                    != PackageManager.PERMISSION_GRANTED) {
5414                if (receiver != null) {
5415                    // If the caller wants to wait for pending thumbnails,
5416                    // it ain't gonna get them.
5417                    try {
5418                        receiver.finished();
5419                    } catch (RemoteException ex) {
5420                    }
5421                }
5422                String msg = "Permission Denial: getTasks() from pid="
5423                        + Binder.getCallingPid()
5424                        + ", uid=" + Binder.getCallingUid()
5425                        + " requires " + android.Manifest.permission.GET_TASKS;
5426                Slog.w(TAG, msg);
5427                throw new SecurityException(msg);
5428            }
5429
5430            int pos = mMainStack.mHistory.size()-1;
5431            ActivityRecord next =
5432                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5433            ActivityRecord top = null;
5434            TaskRecord curTask = null;
5435            int numActivities = 0;
5436            int numRunning = 0;
5437            while (pos >= 0 && maxNum > 0) {
5438                final ActivityRecord r = next;
5439                pos--;
5440                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5441
5442                // Initialize state for next task if needed.
5443                if (top == null ||
5444                        (top.state == ActivityState.INITIALIZING
5445                            && top.task == r.task)) {
5446                    top = r;
5447                    curTask = r.task;
5448                    numActivities = numRunning = 0;
5449                }
5450
5451                // Add 'r' into the current task.
5452                numActivities++;
5453                if (r.app != null && r.app.thread != null) {
5454                    numRunning++;
5455                }
5456
5457                if (localLOGV) Slog.v(
5458                    TAG, r.intent.getComponent().flattenToShortString()
5459                    + ": task=" + r.task);
5460
5461                // If the next one is a different task, generate a new
5462                // TaskInfo entry for what we have.
5463                if (next == null || next.task != curTask) {
5464                    ActivityManager.RunningTaskInfo ci
5465                            = new ActivityManager.RunningTaskInfo();
5466                    ci.id = curTask.taskId;
5467                    ci.baseActivity = r.intent.getComponent();
5468                    ci.topActivity = top.intent.getComponent();
5469                    if (top.thumbHolder != null) {
5470                        ci.description = top.thumbHolder.lastDescription;
5471                    }
5472                    ci.numActivities = numActivities;
5473                    ci.numRunning = numRunning;
5474                    //System.out.println(
5475                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5476                    if (ci.thumbnail == null && receiver != null) {
5477                        if (localLOGV) Slog.v(
5478                            TAG, "State=" + top.state + "Idle=" + top.idle
5479                            + " app=" + top.app
5480                            + " thr=" + (top.app != null ? top.app.thread : null));
5481                        if (top.state == ActivityState.RESUMED
5482                                || top.state == ActivityState.PAUSING) {
5483                            if (top.idle && top.app != null
5484                                && top.app.thread != null) {
5485                                topRecord = top;
5486                                topThumbnail = top.app.thread;
5487                            } else {
5488                                top.thumbnailNeeded = true;
5489                            }
5490                        }
5491                        if (pending == null) {
5492                            pending = new PendingThumbnailsRecord(receiver);
5493                        }
5494                        pending.pendingRecords.add(top);
5495                    }
5496                    list.add(ci);
5497                    maxNum--;
5498                    top = null;
5499                }
5500            }
5501
5502            if (pending != null) {
5503                mPendingThumbnails.add(pending);
5504            }
5505        }
5506
5507        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5508
5509        if (topThumbnail != null) {
5510            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5511            try {
5512                topThumbnail.requestThumbnail(topRecord.appToken);
5513            } catch (Exception e) {
5514                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5515                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5516            }
5517        }
5518
5519        if (pending == null && receiver != null) {
5520            // In this case all thumbnails were available and the client
5521            // is being asked to be told when the remaining ones come in...
5522            // which is unusually, since the top-most currently running
5523            // activity should never have a canned thumbnail!  Oh well.
5524            try {
5525                receiver.finished();
5526            } catch (RemoteException ex) {
5527            }
5528        }
5529
5530        return list;
5531    }
5532
5533    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5534            int flags, int userId) {
5535        final int callingUid = Binder.getCallingUid();
5536        if (userId != UserHandle.getCallingUserId()) {
5537            // Check if the caller is holding permissions for cross-user requests.
5538            if (checkComponentPermission(
5539                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5540                    Binder.getCallingPid(), callingUid, -1, true)
5541                    != PackageManager.PERMISSION_GRANTED) {
5542                String msg = "Permission Denial: "
5543                        + "Request to get recent tasks for user " + userId
5544                        + " but is calling from user " + UserHandle.getUserId(callingUid)
5545                        + "; this requires "
5546                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5547                Slog.w(TAG, msg);
5548                throw new SecurityException(msg);
5549            } else {
5550                if (userId == UserHandle.USER_CURRENT) {
5551                    userId = mCurrentUserId;
5552                }
5553            }
5554        }
5555
5556        synchronized (this) {
5557            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5558                    "getRecentTasks()");
5559            final boolean detailed = checkCallingPermission(
5560                    android.Manifest.permission.GET_DETAILED_TASKS)
5561                    == PackageManager.PERMISSION_GRANTED;
5562
5563            IPackageManager pm = AppGlobals.getPackageManager();
5564
5565            final int N = mRecentTasks.size();
5566            ArrayList<ActivityManager.RecentTaskInfo> res
5567                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5568                            maxNum < N ? maxNum : N);
5569            for (int i=0; i<N && maxNum > 0; i++) {
5570                TaskRecord tr = mRecentTasks.get(i);
5571                // Only add calling user's recent tasks
5572                if (tr.userId != userId) continue;
5573                // Return the entry if desired by the caller.  We always return
5574                // the first entry, because callers always expect this to be the
5575                // foreground app.  We may filter others if the caller has
5576                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5577                // we should exclude the entry.
5578
5579                if (i == 0
5580                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5581                        || (tr.intent == null)
5582                        || ((tr.intent.getFlags()
5583                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5584                    ActivityManager.RecentTaskInfo rti
5585                            = new ActivityManager.RecentTaskInfo();
5586                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5587                    rti.persistentId = tr.taskId;
5588                    rti.baseIntent = new Intent(
5589                            tr.intent != null ? tr.intent : tr.affinityIntent);
5590                    if (!detailed) {
5591                        rti.baseIntent.replaceExtras((Bundle)null);
5592                    }
5593                    rti.origActivity = tr.origActivity;
5594                    rti.description = tr.lastDescription;
5595
5596                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5597                        // Check whether this activity is currently available.
5598                        try {
5599                            if (rti.origActivity != null) {
5600                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5601                                        == null) {
5602                                    continue;
5603                                }
5604                            } else if (rti.baseIntent != null) {
5605                                if (pm.queryIntentActivities(rti.baseIntent,
5606                                        null, 0, userId) == null) {
5607                                    continue;
5608                                }
5609                            }
5610                        } catch (RemoteException e) {
5611                            // Will never happen.
5612                        }
5613                    }
5614
5615                    res.add(rti);
5616                    maxNum--;
5617                }
5618            }
5619            return res;
5620        }
5621    }
5622
5623    private TaskRecord taskForIdLocked(int id) {
5624        final int N = mRecentTasks.size();
5625        for (int i=0; i<N; i++) {
5626            TaskRecord tr = mRecentTasks.get(i);
5627            if (tr.taskId == id) {
5628                return tr;
5629            }
5630        }
5631        return null;
5632    }
5633
5634    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5635        synchronized (this) {
5636            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5637                    "getTaskThumbnails()");
5638            TaskRecord tr = taskForIdLocked(id);
5639            if (tr != null) {
5640                return mMainStack.getTaskThumbnailsLocked(tr);
5641            }
5642        }
5643        return null;
5644    }
5645
5646    public boolean removeSubTask(int taskId, int subTaskIndex) {
5647        synchronized (this) {
5648            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5649                    "removeSubTask()");
5650            long ident = Binder.clearCallingIdentity();
5651            try {
5652                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5653                        true) != null;
5654            } finally {
5655                Binder.restoreCallingIdentity(ident);
5656            }
5657        }
5658    }
5659
5660    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5661        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5662        Intent baseIntent = new Intent(
5663                tr.intent != null ? tr.intent : tr.affinityIntent);
5664        ComponentName component = baseIntent.getComponent();
5665        if (component == null) {
5666            Slog.w(TAG, "Now component for base intent of task: " + tr);
5667            return;
5668        }
5669
5670        // Find any running services associated with this app.
5671        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5672
5673        if (killProcesses) {
5674            // Find any running processes associated with this app.
5675            final String pkg = component.getPackageName();
5676            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5677            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5678            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5679                for (int i=0; i<uids.size(); i++) {
5680                    ProcessRecord proc = uids.valueAt(i);
5681                    if (proc.userId != tr.userId) {
5682                        continue;
5683                    }
5684                    if (!proc.pkgList.contains(pkg)) {
5685                        continue;
5686                    }
5687                    procs.add(proc);
5688                }
5689            }
5690
5691            // Kill the running processes.
5692            for (int i=0; i<procs.size(); i++) {
5693                ProcessRecord pr = procs.get(i);
5694                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5695                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5696                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5697                            pr.processName, pr.setAdj, "remove task");
5698                    pr.killedBackground = true;
5699                    Process.killProcessQuiet(pr.pid);
5700                } else {
5701                    pr.waitingToKill = "remove task";
5702                }
5703            }
5704        }
5705    }
5706
5707    public boolean removeTask(int taskId, int flags) {
5708        synchronized (this) {
5709            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5710                    "removeTask()");
5711            long ident = Binder.clearCallingIdentity();
5712            try {
5713                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5714                        false);
5715                if (r != null) {
5716                    mRecentTasks.remove(r.task);
5717                    cleanUpRemovedTaskLocked(r.task, flags);
5718                    return true;
5719                } else {
5720                    TaskRecord tr = null;
5721                    int i=0;
5722                    while (i < mRecentTasks.size()) {
5723                        TaskRecord t = mRecentTasks.get(i);
5724                        if (t.taskId == taskId) {
5725                            tr = t;
5726                            break;
5727                        }
5728                        i++;
5729                    }
5730                    if (tr != null) {
5731                        if (tr.numActivities <= 0) {
5732                            // Caller is just removing a recent task that is
5733                            // not actively running.  That is easy!
5734                            mRecentTasks.remove(i);
5735                            cleanUpRemovedTaskLocked(tr, flags);
5736                            return true;
5737                        } else {
5738                            Slog.w(TAG, "removeTask: task " + taskId
5739                                    + " does not have activities to remove, "
5740                                    + " but numActivities=" + tr.numActivities
5741                                    + ": " + tr);
5742                        }
5743                    }
5744                }
5745            } finally {
5746                Binder.restoreCallingIdentity(ident);
5747            }
5748        }
5749        return false;
5750    }
5751
5752    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5753        int j;
5754        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5755        TaskRecord jt = startTask;
5756
5757        // First look backwards
5758        for (j=startIndex-1; j>=0; j--) {
5759            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5760            if (r.task != jt) {
5761                jt = r.task;
5762                if (affinity.equals(jt.affinity)) {
5763                    return j;
5764                }
5765            }
5766        }
5767
5768        // Now look forwards
5769        final int N = mMainStack.mHistory.size();
5770        jt = startTask;
5771        for (j=startIndex+1; j<N; j++) {
5772            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5773            if (r.task != jt) {
5774                if (affinity.equals(jt.affinity)) {
5775                    return j;
5776                }
5777                jt = r.task;
5778            }
5779        }
5780
5781        // Might it be at the top?
5782        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5783            return N-1;
5784        }
5785
5786        return -1;
5787    }
5788
5789    /**
5790     * TODO: Add mController hook
5791     */
5792    public void moveTaskToFront(int task, int flags, Bundle options) {
5793        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5794                "moveTaskToFront()");
5795
5796        synchronized(this) {
5797            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5798                    Binder.getCallingUid(), "Task to front")) {
5799                ActivityOptions.abort(options);
5800                return;
5801            }
5802            final long origId = Binder.clearCallingIdentity();
5803            try {
5804                TaskRecord tr = taskForIdLocked(task);
5805                if (tr != null) {
5806                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5807                        mMainStack.mUserLeaving = true;
5808                    }
5809                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5810                        // Caller wants the home activity moved with it.  To accomplish this,
5811                        // we'll just move the home task to the top first.
5812                        mMainStack.moveHomeToFrontLocked();
5813                    }
5814                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5815                    return;
5816                }
5817                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5818                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5819                    if (hr.task.taskId == task) {
5820                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5821                            mMainStack.mUserLeaving = true;
5822                        }
5823                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5824                            // Caller wants the home activity moved with it.  To accomplish this,
5825                            // we'll just move the home task to the top first.
5826                            mMainStack.moveHomeToFrontLocked();
5827                        }
5828                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5829                        return;
5830                    }
5831                }
5832            } finally {
5833                Binder.restoreCallingIdentity(origId);
5834            }
5835            ActivityOptions.abort(options);
5836        }
5837    }
5838
5839    public void moveTaskToBack(int task) {
5840        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5841                "moveTaskToBack()");
5842
5843        synchronized(this) {
5844            if (mMainStack.mResumedActivity != null
5845                    && mMainStack.mResumedActivity.task.taskId == task) {
5846                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5847                        Binder.getCallingUid(), "Task to back")) {
5848                    return;
5849                }
5850            }
5851            final long origId = Binder.clearCallingIdentity();
5852            mMainStack.moveTaskToBackLocked(task, null);
5853            Binder.restoreCallingIdentity(origId);
5854        }
5855    }
5856
5857    /**
5858     * Moves an activity, and all of the other activities within the same task, to the bottom
5859     * of the history stack.  The activity's order within the task is unchanged.
5860     *
5861     * @param token A reference to the activity we wish to move
5862     * @param nonRoot If false then this only works if the activity is the root
5863     *                of a task; if true it will work for any activity in a task.
5864     * @return Returns true if the move completed, false if not.
5865     */
5866    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5867        enforceNotIsolatedCaller("moveActivityTaskToBack");
5868        synchronized(this) {
5869            final long origId = Binder.clearCallingIdentity();
5870            int taskId = getTaskForActivityLocked(token, !nonRoot);
5871            if (taskId >= 0) {
5872                return mMainStack.moveTaskToBackLocked(taskId, null);
5873            }
5874            Binder.restoreCallingIdentity(origId);
5875        }
5876        return false;
5877    }
5878
5879    public void moveTaskBackwards(int task) {
5880        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5881                "moveTaskBackwards()");
5882
5883        synchronized(this) {
5884            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5885                    Binder.getCallingUid(), "Task backwards")) {
5886                return;
5887            }
5888            final long origId = Binder.clearCallingIdentity();
5889            moveTaskBackwardsLocked(task);
5890            Binder.restoreCallingIdentity(origId);
5891        }
5892    }
5893
5894    private final void moveTaskBackwardsLocked(int task) {
5895        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5896    }
5897
5898    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5899        synchronized(this) {
5900            return getTaskForActivityLocked(token, onlyRoot);
5901        }
5902    }
5903
5904    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5905        final int N = mMainStack.mHistory.size();
5906        TaskRecord lastTask = null;
5907        for (int i=0; i<N; i++) {
5908            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5909            if (r.appToken == token) {
5910                if (!onlyRoot || lastTask != r.task) {
5911                    return r.task.taskId;
5912                }
5913                return -1;
5914            }
5915            lastTask = r.task;
5916        }
5917
5918        return -1;
5919    }
5920
5921    // =========================================================
5922    // THUMBNAILS
5923    // =========================================================
5924
5925    public void reportThumbnail(IBinder token,
5926            Bitmap thumbnail, CharSequence description) {
5927        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5928        final long origId = Binder.clearCallingIdentity();
5929        sendPendingThumbnail(null, token, thumbnail, description, true);
5930        Binder.restoreCallingIdentity(origId);
5931    }
5932
5933    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5934            Bitmap thumbnail, CharSequence description, boolean always) {
5935        TaskRecord task = null;
5936        ArrayList receivers = null;
5937
5938        //System.out.println("Send pending thumbnail: " + r);
5939
5940        synchronized(this) {
5941            if (r == null) {
5942                r = mMainStack.isInStackLocked(token);
5943                if (r == null) {
5944                    return;
5945                }
5946            }
5947            if (thumbnail == null && r.thumbHolder != null) {
5948                thumbnail = r.thumbHolder.lastThumbnail;
5949                description = r.thumbHolder.lastDescription;
5950            }
5951            if (thumbnail == null && !always) {
5952                // If there is no thumbnail, and this entry is not actually
5953                // going away, then abort for now and pick up the next
5954                // thumbnail we get.
5955                return;
5956            }
5957            task = r.task;
5958
5959            int N = mPendingThumbnails.size();
5960            int i=0;
5961            while (i<N) {
5962                PendingThumbnailsRecord pr =
5963                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5964                //System.out.println("Looking in " + pr.pendingRecords);
5965                if (pr.pendingRecords.remove(r)) {
5966                    if (receivers == null) {
5967                        receivers = new ArrayList();
5968                    }
5969                    receivers.add(pr);
5970                    if (pr.pendingRecords.size() == 0) {
5971                        pr.finished = true;
5972                        mPendingThumbnails.remove(i);
5973                        N--;
5974                        continue;
5975                    }
5976                }
5977                i++;
5978            }
5979        }
5980
5981        if (receivers != null) {
5982            final int N = receivers.size();
5983            for (int i=0; i<N; i++) {
5984                try {
5985                    PendingThumbnailsRecord pr =
5986                        (PendingThumbnailsRecord)receivers.get(i);
5987                    pr.receiver.newThumbnail(
5988                        task != null ? task.taskId : -1, thumbnail, description);
5989                    if (pr.finished) {
5990                        pr.receiver.finished();
5991                    }
5992                } catch (Exception e) {
5993                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
5994                }
5995            }
5996        }
5997    }
5998
5999    // =========================================================
6000    // CONTENT PROVIDERS
6001    // =========================================================
6002
6003    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6004        List<ProviderInfo> providers = null;
6005        try {
6006            providers = AppGlobals.getPackageManager().
6007                queryContentProviders(app.processName, app.uid,
6008                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6009        } catch (RemoteException ex) {
6010        }
6011        if (DEBUG_MU)
6012            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6013        int userId = app.userId;
6014        if (providers != null) {
6015            int N = providers.size();
6016            for (int i=0; i<N; i++) {
6017                ProviderInfo cpi =
6018                    (ProviderInfo)providers.get(i);
6019                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6020                        cpi.name, cpi.flags);
6021                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6022                    // This is a singleton provider, but a user besides the
6023                    // default user is asking to initialize a process it runs
6024                    // in...  well, no, it doesn't actually run in this process,
6025                    // it runs in the process of the default user.  Get rid of it.
6026                    providers.remove(i);
6027                    N--;
6028                    continue;
6029                }
6030
6031                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6032                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6033                if (cpr == null) {
6034                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6035                    mProviderMap.putProviderByClass(comp, cpr);
6036                }
6037                if (DEBUG_MU)
6038                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6039                app.pubProviders.put(cpi.name, cpr);
6040                app.addPackage(cpi.applicationInfo.packageName);
6041                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6042            }
6043        }
6044        return providers;
6045    }
6046
6047    /**
6048     * Check if {@link ProcessRecord} has a possible chance at accessing the
6049     * given {@link ProviderInfo}. Final permission checking is always done
6050     * in {@link ContentProvider}.
6051     */
6052    private final String checkContentProviderPermissionLocked(
6053            ProviderInfo cpi, ProcessRecord r) {
6054        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6055        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6056        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6057                cpi.applicationInfo.uid, cpi.exported)
6058                == PackageManager.PERMISSION_GRANTED) {
6059            return null;
6060        }
6061        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6062                cpi.applicationInfo.uid, cpi.exported)
6063                == PackageManager.PERMISSION_GRANTED) {
6064            return null;
6065        }
6066
6067        PathPermission[] pps = cpi.pathPermissions;
6068        if (pps != null) {
6069            int i = pps.length;
6070            while (i > 0) {
6071                i--;
6072                PathPermission pp = pps[i];
6073                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6074                        cpi.applicationInfo.uid, cpi.exported)
6075                        == PackageManager.PERMISSION_GRANTED) {
6076                    return null;
6077                }
6078                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6079                        cpi.applicationInfo.uid, cpi.exported)
6080                        == PackageManager.PERMISSION_GRANTED) {
6081                    return null;
6082                }
6083            }
6084        }
6085
6086        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6087        if (perms != null) {
6088            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6089                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6090                    return null;
6091                }
6092            }
6093        }
6094
6095        String msg;
6096        if (!cpi.exported) {
6097            msg = "Permission Denial: opening provider " + cpi.name
6098                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6099                    + ", uid=" + callingUid + ") that is not exported from uid "
6100                    + cpi.applicationInfo.uid;
6101        } else {
6102            msg = "Permission Denial: opening provider " + cpi.name
6103                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6104                    + ", uid=" + callingUid + ") requires "
6105                    + cpi.readPermission + " or " + cpi.writePermission;
6106        }
6107        Slog.w(TAG, msg);
6108        return msg;
6109    }
6110
6111    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6112            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6113        if (r != null) {
6114            for (int i=0; i<r.conProviders.size(); i++) {
6115                ContentProviderConnection conn = r.conProviders.get(i);
6116                if (conn.provider == cpr) {
6117                    if (DEBUG_PROVIDER) Slog.v(TAG,
6118                            "Adding provider requested by "
6119                            + r.processName + " from process "
6120                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6121                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6122                    if (stable) {
6123                        conn.stableCount++;
6124                        conn.numStableIncs++;
6125                    } else {
6126                        conn.unstableCount++;
6127                        conn.numUnstableIncs++;
6128                    }
6129                    return conn;
6130                }
6131            }
6132            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6133            if (stable) {
6134                conn.stableCount = 1;
6135                conn.numStableIncs = 1;
6136            } else {
6137                conn.unstableCount = 1;
6138                conn.numUnstableIncs = 1;
6139            }
6140            cpr.connections.add(conn);
6141            r.conProviders.add(conn);
6142            return conn;
6143        }
6144        cpr.addExternalProcessHandleLocked(externalProcessToken);
6145        return null;
6146    }
6147
6148    boolean decProviderCountLocked(ContentProviderConnection conn,
6149            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6150        if (conn != null) {
6151            cpr = conn.provider;
6152            if (DEBUG_PROVIDER) Slog.v(TAG,
6153                    "Removing provider requested by "
6154                    + conn.client.processName + " from process "
6155                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6156                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6157            if (stable) {
6158                conn.stableCount--;
6159            } else {
6160                conn.unstableCount--;
6161            }
6162            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6163                cpr.connections.remove(conn);
6164                conn.client.conProviders.remove(conn);
6165                return true;
6166            }
6167            return false;
6168        }
6169        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6170        return false;
6171    }
6172
6173    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6174            String name, IBinder token, boolean stable) {
6175        ContentProviderRecord cpr;
6176        ContentProviderConnection conn = null;
6177        ProviderInfo cpi = null;
6178
6179        synchronized(this) {
6180            ProcessRecord r = null;
6181            if (caller != null) {
6182                r = getRecordForAppLocked(caller);
6183                if (r == null) {
6184                    throw new SecurityException(
6185                            "Unable to find app for caller " + caller
6186                          + " (pid=" + Binder.getCallingPid()
6187                          + ") when getting content provider " + name);
6188                }
6189            }
6190
6191            // First check if this content provider has been published...
6192            int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid());
6193            cpr = mProviderMap.getProviderByName(name, userId);
6194            boolean providerRunning = cpr != null;
6195            if (providerRunning) {
6196                cpi = cpr.info;
6197                String msg;
6198                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6199                    throw new SecurityException(msg);
6200                }
6201
6202                if (r != null && cpr.canRunHere(r)) {
6203                    // This provider has been published or is in the process
6204                    // of being published...  but it is also allowed to run
6205                    // in the caller's process, so don't make a connection
6206                    // and just let the caller instantiate its own instance.
6207                    ContentProviderHolder holder = cpr.newHolder(null);
6208                    // don't give caller the provider object, it needs
6209                    // to make its own.
6210                    holder.provider = null;
6211                    return holder;
6212                }
6213
6214                final long origId = Binder.clearCallingIdentity();
6215
6216                // In this case the provider instance already exists, so we can
6217                // return it right away.
6218                conn = incProviderCountLocked(r, cpr, token, stable);
6219                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6220                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6221                        // If this is a perceptible app accessing the provider,
6222                        // make sure to count it as being accessed and thus
6223                        // back up on the LRU list.  This is good because
6224                        // content providers are often expensive to start.
6225                        updateLruProcessLocked(cpr.proc, false, true);
6226                    }
6227                }
6228
6229                if (cpr.proc != null) {
6230                    if (false) {
6231                        if (cpr.name.flattenToShortString().equals(
6232                                "com.android.providers.calendar/.CalendarProvider2")) {
6233                            Slog.v(TAG, "****************** KILLING "
6234                                + cpr.name.flattenToShortString());
6235                            Process.killProcess(cpr.proc.pid);
6236                        }
6237                    }
6238                    boolean success = updateOomAdjLocked(cpr.proc);
6239                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6240                    // NOTE: there is still a race here where a signal could be
6241                    // pending on the process even though we managed to update its
6242                    // adj level.  Not sure what to do about this, but at least
6243                    // the race is now smaller.
6244                    if (!success) {
6245                        // Uh oh...  it looks like the provider's process
6246                        // has been killed on us.  We need to wait for a new
6247                        // process to be started, and make sure its death
6248                        // doesn't kill our process.
6249                        Slog.i(TAG,
6250                                "Existing provider " + cpr.name.flattenToShortString()
6251                                + " is crashing; detaching " + r);
6252                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6253                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6254                        if (!lastRef) {
6255                            // This wasn't the last ref our process had on
6256                            // the provider...  we have now been killed, bail.
6257                            return null;
6258                        }
6259                        providerRunning = false;
6260                        conn = null;
6261                    }
6262                }
6263
6264                Binder.restoreCallingIdentity(origId);
6265            }
6266
6267            boolean singleton;
6268            if (!providerRunning) {
6269                try {
6270                    cpi = AppGlobals.getPackageManager().
6271                        resolveContentProvider(name,
6272                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6273                } catch (RemoteException ex) {
6274                }
6275                if (cpi == null) {
6276                    return null;
6277                }
6278                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6279                        cpi.name, cpi.flags);
6280                if (singleton) {
6281                    userId = 0;
6282                }
6283                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6284
6285                String msg;
6286                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6287                    throw new SecurityException(msg);
6288                }
6289
6290                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6291                        && !cpi.processName.equals("system")) {
6292                    // If this content provider does not run in the system
6293                    // process, and the system is not yet ready to run other
6294                    // processes, then fail fast instead of hanging.
6295                    throw new IllegalArgumentException(
6296                            "Attempt to launch content provider before system ready");
6297                }
6298
6299                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6300                cpr = mProviderMap.getProviderByClass(comp, userId);
6301                final boolean firstClass = cpr == null;
6302                if (firstClass) {
6303                    try {
6304                        ApplicationInfo ai =
6305                            AppGlobals.getPackageManager().
6306                                getApplicationInfo(
6307                                        cpi.applicationInfo.packageName,
6308                                        STOCK_PM_FLAGS, userId);
6309                        if (ai == null) {
6310                            Slog.w(TAG, "No package info for content provider "
6311                                    + cpi.name);
6312                            return null;
6313                        }
6314                        ai = getAppInfoForUser(ai, userId);
6315                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6316                    } catch (RemoteException ex) {
6317                        // pm is in same process, this will never happen.
6318                    }
6319                }
6320
6321                if (r != null && cpr.canRunHere(r)) {
6322                    // If this is a multiprocess provider, then just return its
6323                    // info and allow the caller to instantiate it.  Only do
6324                    // this if the provider is the same user as the caller's
6325                    // process, or can run as root (so can be in any process).
6326                    return cpr.newHolder(null);
6327                }
6328
6329                if (DEBUG_PROVIDER) {
6330                    RuntimeException e = new RuntimeException("here");
6331                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6332                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6333                }
6334
6335                // This is single process, and our app is now connecting to it.
6336                // See if we are already in the process of launching this
6337                // provider.
6338                final int N = mLaunchingProviders.size();
6339                int i;
6340                for (i=0; i<N; i++) {
6341                    if (mLaunchingProviders.get(i) == cpr) {
6342                        break;
6343                    }
6344                }
6345
6346                // If the provider is not already being launched, then get it
6347                // started.
6348                if (i >= N) {
6349                    final long origId = Binder.clearCallingIdentity();
6350
6351                    try {
6352                        // Content provider is now in use, its package can't be stopped.
6353                        try {
6354                            AppGlobals.getPackageManager().setPackageStoppedState(
6355                                    cpr.appInfo.packageName, false, userId);
6356                        } catch (RemoteException e) {
6357                        } catch (IllegalArgumentException e) {
6358                            Slog.w(TAG, "Failed trying to unstop package "
6359                                    + cpr.appInfo.packageName + ": " + e);
6360                        }
6361
6362                        ProcessRecord proc = startProcessLocked(cpi.processName,
6363                                cpr.appInfo, false, 0, "content provider",
6364                                new ComponentName(cpi.applicationInfo.packageName,
6365                                        cpi.name), false, false);
6366                        if (proc == null) {
6367                            Slog.w(TAG, "Unable to launch app "
6368                                    + cpi.applicationInfo.packageName + "/"
6369                                    + cpi.applicationInfo.uid + " for provider "
6370                                    + name + ": process is bad");
6371                            return null;
6372                        }
6373                        cpr.launchingApp = proc;
6374                        mLaunchingProviders.add(cpr);
6375                    } finally {
6376                        Binder.restoreCallingIdentity(origId);
6377                    }
6378                }
6379
6380                // Make sure the provider is published (the same provider class
6381                // may be published under multiple names).
6382                if (firstClass) {
6383                    mProviderMap.putProviderByClass(comp, cpr);
6384                }
6385
6386                mProviderMap.putProviderByName(name, cpr);
6387                conn = incProviderCountLocked(r, cpr, token, stable);
6388                if (conn != null) {
6389                    conn.waiting = true;
6390                }
6391            }
6392        }
6393
6394        // Wait for the provider to be published...
6395        synchronized (cpr) {
6396            while (cpr.provider == null) {
6397                if (cpr.launchingApp == null) {
6398                    Slog.w(TAG, "Unable to launch app "
6399                            + cpi.applicationInfo.packageName + "/"
6400                            + cpi.applicationInfo.uid + " for provider "
6401                            + name + ": launching app became null");
6402                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6403                            cpi.applicationInfo.packageName,
6404                            cpi.applicationInfo.uid, name);
6405                    return null;
6406                }
6407                try {
6408                    if (DEBUG_MU) {
6409                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6410                                + cpr.launchingApp);
6411                    }
6412                    if (conn != null) {
6413                        conn.waiting = true;
6414                    }
6415                    cpr.wait();
6416                } catch (InterruptedException ex) {
6417                } finally {
6418                    if (conn != null) {
6419                        conn.waiting = false;
6420                    }
6421                }
6422            }
6423        }
6424        return cpr != null ? cpr.newHolder(conn) : null;
6425    }
6426
6427    public final ContentProviderHolder getContentProvider(
6428            IApplicationThread caller, String name, boolean stable) {
6429        enforceNotIsolatedCaller("getContentProvider");
6430        if (caller == null) {
6431            String msg = "null IApplicationThread when getting content provider "
6432                    + name;
6433            Slog.w(TAG, msg);
6434            throw new SecurityException(msg);
6435        }
6436
6437        return getContentProviderImpl(caller, name, null, stable);
6438    }
6439
6440    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6441        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6442            "Do not have permission in call getContentProviderExternal()");
6443        return getContentProviderExternalUnchecked(name, token);
6444    }
6445
6446    private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
6447        return getContentProviderImpl(null, name, token, true);
6448    }
6449
6450    /**
6451     * Drop a content provider from a ProcessRecord's bookkeeping
6452     * @param cpr
6453     */
6454    public void removeContentProvider(IBinder connection, boolean stable) {
6455        enforceNotIsolatedCaller("removeContentProvider");
6456        synchronized (this) {
6457            ContentProviderConnection conn;
6458            try {
6459                conn = (ContentProviderConnection)connection;
6460            } catch (ClassCastException e) {
6461                String msg ="removeContentProvider: " + connection
6462                        + " not a ContentProviderConnection";
6463                Slog.w(TAG, msg);
6464                throw new IllegalArgumentException(msg);
6465            }
6466            if (conn == null) {
6467                throw new NullPointerException("connection is null");
6468            }
6469            if (decProviderCountLocked(conn, null, null, stable)) {
6470                updateOomAdjLocked();
6471            }
6472        }
6473    }
6474
6475    public void removeContentProviderExternal(String name, IBinder token) {
6476        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6477            "Do not have permission in call removeContentProviderExternal()");
6478        removeContentProviderExternalUnchecked(name, token);
6479    }
6480
6481    private void removeContentProviderExternalUnchecked(String name, IBinder token) {
6482        synchronized (this) {
6483            ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6484                    Binder.getOrigCallingUser());
6485            if(cpr == null) {
6486                //remove from mProvidersByClass
6487                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6488                return;
6489            }
6490
6491            //update content provider record entry info
6492            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6493            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
6494                    Binder.getOrigCallingUser());
6495            if (localCpr.hasExternalProcessHandles()) {
6496                if (localCpr.removeExternalProcessHandleLocked(token)) {
6497                    updateOomAdjLocked();
6498                } else {
6499                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6500                            + " with no external reference for token: "
6501                            + token + ".");
6502                }
6503            } else {
6504                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6505                        + " with no external references.");
6506            }
6507        }
6508    }
6509
6510    public final void publishContentProviders(IApplicationThread caller,
6511            List<ContentProviderHolder> providers) {
6512        if (providers == null) {
6513            return;
6514        }
6515
6516        enforceNotIsolatedCaller("publishContentProviders");
6517        synchronized (this) {
6518            final ProcessRecord r = getRecordForAppLocked(caller);
6519            if (DEBUG_MU)
6520                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6521            if (r == null) {
6522                throw new SecurityException(
6523                        "Unable to find app for caller " + caller
6524                      + " (pid=" + Binder.getCallingPid()
6525                      + ") when publishing content providers");
6526            }
6527
6528            final long origId = Binder.clearCallingIdentity();
6529
6530            final int N = providers.size();
6531            for (int i=0; i<N; i++) {
6532                ContentProviderHolder src = providers.get(i);
6533                if (src == null || src.info == null || src.provider == null) {
6534                    continue;
6535                }
6536                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6537                if (DEBUG_MU)
6538                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6539                if (dst != null) {
6540                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6541                    mProviderMap.putProviderByClass(comp, dst);
6542                    String names[] = dst.info.authority.split(";");
6543                    for (int j = 0; j < names.length; j++) {
6544                        mProviderMap.putProviderByName(names[j], dst);
6545                    }
6546
6547                    int NL = mLaunchingProviders.size();
6548                    int j;
6549                    for (j=0; j<NL; j++) {
6550                        if (mLaunchingProviders.get(j) == dst) {
6551                            mLaunchingProviders.remove(j);
6552                            j--;
6553                            NL--;
6554                        }
6555                    }
6556                    synchronized (dst) {
6557                        dst.provider = src.provider;
6558                        dst.proc = r;
6559                        dst.notifyAll();
6560                    }
6561                    updateOomAdjLocked(r);
6562                }
6563            }
6564
6565            Binder.restoreCallingIdentity(origId);
6566        }
6567    }
6568
6569    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6570        ContentProviderConnection conn;
6571        try {
6572            conn = (ContentProviderConnection)connection;
6573        } catch (ClassCastException e) {
6574            String msg ="refContentProvider: " + connection
6575                    + " not a ContentProviderConnection";
6576            Slog.w(TAG, msg);
6577            throw new IllegalArgumentException(msg);
6578        }
6579        if (conn == null) {
6580            throw new NullPointerException("connection is null");
6581        }
6582
6583        synchronized (this) {
6584            if (stable > 0) {
6585                conn.numStableIncs += stable;
6586            }
6587            stable = conn.stableCount + stable;
6588            if (stable < 0) {
6589                throw new IllegalStateException("stableCount < 0: " + stable);
6590            }
6591
6592            if (unstable > 0) {
6593                conn.numUnstableIncs += unstable;
6594            }
6595            unstable = conn.unstableCount + unstable;
6596            if (unstable < 0) {
6597                throw new IllegalStateException("unstableCount < 0: " + unstable);
6598            }
6599
6600            if ((stable+unstable) <= 0) {
6601                throw new IllegalStateException("ref counts can't go to zero here: stable="
6602                        + stable + " unstable=" + unstable);
6603            }
6604            conn.stableCount = stable;
6605            conn.unstableCount = unstable;
6606            return !conn.dead;
6607        }
6608    }
6609
6610    public void unstableProviderDied(IBinder connection) {
6611        ContentProviderConnection conn;
6612        try {
6613            conn = (ContentProviderConnection)connection;
6614        } catch (ClassCastException e) {
6615            String msg ="refContentProvider: " + connection
6616                    + " not a ContentProviderConnection";
6617            Slog.w(TAG, msg);
6618            throw new IllegalArgumentException(msg);
6619        }
6620        if (conn == null) {
6621            throw new NullPointerException("connection is null");
6622        }
6623
6624        // Safely retrieve the content provider associated with the connection.
6625        IContentProvider provider;
6626        synchronized (this) {
6627            provider = conn.provider.provider;
6628        }
6629
6630        if (provider == null) {
6631            // Um, yeah, we're way ahead of you.
6632            return;
6633        }
6634
6635        // Make sure the caller is being honest with us.
6636        if (provider.asBinder().pingBinder()) {
6637            // Er, no, still looks good to us.
6638            synchronized (this) {
6639                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6640                        + " says " + conn + " died, but we don't agree");
6641                return;
6642            }
6643        }
6644
6645        // Well look at that!  It's dead!
6646        synchronized (this) {
6647            if (conn.provider.provider != provider) {
6648                // But something changed...  good enough.
6649                return;
6650            }
6651
6652            ProcessRecord proc = conn.provider.proc;
6653            if (proc == null || proc.thread == null) {
6654                // Seems like the process is already cleaned up.
6655                return;
6656            }
6657
6658            // As far as we're concerned, this is just like receiving a
6659            // death notification...  just a bit prematurely.
6660            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6661                    + ") early provider death");
6662            final long ident = Binder.clearCallingIdentity();
6663            try {
6664                appDiedLocked(proc, proc.pid, proc.thread);
6665            } finally {
6666                Binder.restoreCallingIdentity(ident);
6667            }
6668        }
6669    }
6670
6671    public static final void installSystemProviders() {
6672        List<ProviderInfo> providers;
6673        synchronized (mSelf) {
6674            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6675            providers = mSelf.generateApplicationProvidersLocked(app);
6676            if (providers != null) {
6677                for (int i=providers.size()-1; i>=0; i--) {
6678                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6679                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6680                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6681                                + ": not system .apk");
6682                        providers.remove(i);
6683                    }
6684                }
6685            }
6686        }
6687        if (providers != null) {
6688            mSystemThread.installSystemProviders(providers);
6689        }
6690
6691        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6692
6693        mSelf.mUsageStatsService.monitorPackages();
6694    }
6695
6696    /**
6697     * Allows app to retrieve the MIME type of a URI without having permission
6698     * to access its content provider.
6699     *
6700     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6701     *
6702     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6703     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6704     */
6705    public String getProviderMimeType(Uri uri) {
6706        enforceNotIsolatedCaller("getProviderMimeType");
6707        final String name = uri.getAuthority();
6708        final long ident = Binder.clearCallingIdentity();
6709        ContentProviderHolder holder = null;
6710
6711        try {
6712            holder = getContentProviderExternalUnchecked(name, null);
6713            if (holder != null) {
6714                return holder.provider.getType(uri);
6715            }
6716        } catch (RemoteException e) {
6717            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6718            return null;
6719        } finally {
6720            if (holder != null) {
6721                removeContentProviderExternalUnchecked(name, null);
6722            }
6723            Binder.restoreCallingIdentity(ident);
6724        }
6725
6726        return null;
6727    }
6728
6729    // =========================================================
6730    // GLOBAL MANAGEMENT
6731    // =========================================================
6732
6733    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6734            ApplicationInfo info, String customProcess, boolean isolated) {
6735        String proc = customProcess != null ? customProcess : info.processName;
6736        BatteryStatsImpl.Uid.Proc ps = null;
6737        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6738        int uid = info.uid;
6739        if (isolated) {
6740            int userId = UserHandle.getUserId(uid);
6741            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6742            uid = 0;
6743            while (true) {
6744                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6745                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6746                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6747                }
6748                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6749                mNextIsolatedProcessUid++;
6750                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6751                    // No process for this uid, use it.
6752                    break;
6753                }
6754                stepsLeft--;
6755                if (stepsLeft <= 0) {
6756                    return null;
6757                }
6758            }
6759        }
6760        synchronized (stats) {
6761            ps = stats.getProcessStatsLocked(info.uid, proc);
6762        }
6763        return new ProcessRecord(ps, thread, info, proc, uid);
6764    }
6765
6766    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6767        ProcessRecord app;
6768        if (!isolated) {
6769            app = getProcessRecordLocked(info.processName, info.uid);
6770        } else {
6771            app = null;
6772        }
6773
6774        if (app == null) {
6775            app = newProcessRecordLocked(null, info, null, isolated);
6776            mProcessNames.put(info.processName, app.uid, app);
6777            if (isolated) {
6778                mIsolatedProcesses.put(app.uid, app);
6779            }
6780            updateLruProcessLocked(app, true, true);
6781        }
6782
6783        // This package really, really can not be stopped.
6784        try {
6785            AppGlobals.getPackageManager().setPackageStoppedState(
6786                    info.packageName, false, UserHandle.getUserId(app.uid));
6787        } catch (RemoteException e) {
6788        } catch (IllegalArgumentException e) {
6789            Slog.w(TAG, "Failed trying to unstop package "
6790                    + info.packageName + ": " + e);
6791        }
6792
6793        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6794                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6795            app.persistent = true;
6796            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6797        }
6798        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6799            mPersistentStartingProcesses.add(app);
6800            startProcessLocked(app, "added application", app.processName);
6801        }
6802
6803        return app;
6804    }
6805
6806    public void unhandledBack() {
6807        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6808                "unhandledBack()");
6809
6810        synchronized(this) {
6811            int count = mMainStack.mHistory.size();
6812            if (DEBUG_SWITCH) Slog.d(
6813                TAG, "Performing unhandledBack(): stack size = " + count);
6814            if (count > 1) {
6815                final long origId = Binder.clearCallingIdentity();
6816                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6817                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6818                Binder.restoreCallingIdentity(origId);
6819            }
6820        }
6821    }
6822
6823    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6824        enforceNotIsolatedCaller("openContentUri");
6825        String name = uri.getAuthority();
6826        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
6827        ParcelFileDescriptor pfd = null;
6828        if (cph != null) {
6829            // We record the binder invoker's uid in thread-local storage before
6830            // going to the content provider to open the file.  Later, in the code
6831            // that handles all permissions checks, we look for this uid and use
6832            // that rather than the Activity Manager's own uid.  The effect is that
6833            // we do the check against the caller's permissions even though it looks
6834            // to the content provider like the Activity Manager itself is making
6835            // the request.
6836            sCallerIdentity.set(new Identity(
6837                    Binder.getCallingPid(), Binder.getCallingUid()));
6838            try {
6839                pfd = cph.provider.openFile(uri, "r");
6840            } catch (FileNotFoundException e) {
6841                // do nothing; pfd will be returned null
6842            } finally {
6843                // Ensure that whatever happens, we clean up the identity state
6844                sCallerIdentity.remove();
6845            }
6846
6847            // We've got the fd now, so we're done with the provider.
6848            removeContentProviderExternalUnchecked(name, null);
6849        } else {
6850            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6851        }
6852        return pfd;
6853    }
6854
6855    // Actually is sleeping or shutting down or whatever else in the future
6856    // is an inactive state.
6857    public boolean isSleeping() {
6858        return mSleeping || mShuttingDown;
6859    }
6860
6861    public void goingToSleep() {
6862        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6863                != PackageManager.PERMISSION_GRANTED) {
6864            throw new SecurityException("Requires permission "
6865                    + android.Manifest.permission.DEVICE_POWER);
6866        }
6867
6868        synchronized(this) {
6869            mWentToSleep = true;
6870            updateEventDispatchingLocked();
6871
6872            if (!mSleeping) {
6873                mSleeping = true;
6874                mMainStack.stopIfSleepingLocked();
6875
6876                // Initialize the wake times of all processes.
6877                checkExcessivePowerUsageLocked(false);
6878                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6879                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6880                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6881            }
6882        }
6883    }
6884
6885    public boolean shutdown(int timeout) {
6886        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6887                != PackageManager.PERMISSION_GRANTED) {
6888            throw new SecurityException("Requires permission "
6889                    + android.Manifest.permission.SHUTDOWN);
6890        }
6891
6892        boolean timedout = false;
6893
6894        synchronized(this) {
6895            mShuttingDown = true;
6896            updateEventDispatchingLocked();
6897
6898            if (mMainStack.mResumedActivity != null) {
6899                mMainStack.stopIfSleepingLocked();
6900                final long endTime = System.currentTimeMillis() + timeout;
6901                while (mMainStack.mResumedActivity != null
6902                        || mMainStack.mPausingActivity != null) {
6903                    long delay = endTime - System.currentTimeMillis();
6904                    if (delay <= 0) {
6905                        Slog.w(TAG, "Activity manager shutdown timed out");
6906                        timedout = true;
6907                        break;
6908                    }
6909                    try {
6910                        this.wait();
6911                    } catch (InterruptedException e) {
6912                    }
6913                }
6914            }
6915        }
6916
6917        mUsageStatsService.shutdown();
6918        mBatteryStatsService.shutdown();
6919
6920        return timedout;
6921    }
6922
6923    public final void activitySlept(IBinder token) {
6924        if (localLOGV) Slog.v(
6925            TAG, "Activity slept: token=" + token);
6926
6927        ActivityRecord r = null;
6928
6929        final long origId = Binder.clearCallingIdentity();
6930
6931        synchronized (this) {
6932            r = mMainStack.isInStackLocked(token);
6933            if (r != null) {
6934                mMainStack.activitySleptLocked(r);
6935            }
6936        }
6937
6938        Binder.restoreCallingIdentity(origId);
6939    }
6940
6941    private void comeOutOfSleepIfNeededLocked() {
6942        if (!mWentToSleep && !mLockScreenShown) {
6943            if (mSleeping) {
6944                mSleeping = false;
6945                mMainStack.awakeFromSleepingLocked();
6946                mMainStack.resumeTopActivityLocked(null);
6947            }
6948        }
6949    }
6950
6951    public void wakingUp() {
6952        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6953                != PackageManager.PERMISSION_GRANTED) {
6954            throw new SecurityException("Requires permission "
6955                    + android.Manifest.permission.DEVICE_POWER);
6956        }
6957
6958        synchronized(this) {
6959            mWentToSleep = false;
6960            updateEventDispatchingLocked();
6961            comeOutOfSleepIfNeededLocked();
6962        }
6963    }
6964
6965    private void updateEventDispatchingLocked() {
6966        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
6967    }
6968
6969    public void setLockScreenShown(boolean shown) {
6970        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6971                != PackageManager.PERMISSION_GRANTED) {
6972            throw new SecurityException("Requires permission "
6973                    + android.Manifest.permission.DEVICE_POWER);
6974        }
6975
6976        synchronized(this) {
6977            mLockScreenShown = shown;
6978            comeOutOfSleepIfNeededLocked();
6979        }
6980    }
6981
6982    public void stopAppSwitches() {
6983        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6984                != PackageManager.PERMISSION_GRANTED) {
6985            throw new SecurityException("Requires permission "
6986                    + android.Manifest.permission.STOP_APP_SWITCHES);
6987        }
6988
6989        synchronized(this) {
6990            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6991                    + APP_SWITCH_DELAY_TIME;
6992            mDidAppSwitch = false;
6993            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6994            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6995            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6996        }
6997    }
6998
6999    public void resumeAppSwitches() {
7000        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7001                != PackageManager.PERMISSION_GRANTED) {
7002            throw new SecurityException("Requires permission "
7003                    + android.Manifest.permission.STOP_APP_SWITCHES);
7004        }
7005
7006        synchronized(this) {
7007            // Note that we don't execute any pending app switches... we will
7008            // let those wait until either the timeout, or the next start
7009            // activity request.
7010            mAppSwitchesAllowedTime = 0;
7011        }
7012    }
7013
7014    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7015            String name) {
7016        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7017            return true;
7018        }
7019
7020        final int perm = checkComponentPermission(
7021                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7022                callingUid, -1, true);
7023        if (perm == PackageManager.PERMISSION_GRANTED) {
7024            return true;
7025        }
7026
7027        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7028        return false;
7029    }
7030
7031    public void setDebugApp(String packageName, boolean waitForDebugger,
7032            boolean persistent) {
7033        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7034                "setDebugApp()");
7035
7036        // Note that this is not really thread safe if there are multiple
7037        // callers into it at the same time, but that's not a situation we
7038        // care about.
7039        if (persistent) {
7040            final ContentResolver resolver = mContext.getContentResolver();
7041            Settings.System.putString(
7042                resolver, Settings.System.DEBUG_APP,
7043                packageName);
7044            Settings.System.putInt(
7045                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7046                waitForDebugger ? 1 : 0);
7047        }
7048
7049        synchronized (this) {
7050            if (!persistent) {
7051                mOrigDebugApp = mDebugApp;
7052                mOrigWaitForDebugger = mWaitForDebugger;
7053            }
7054            mDebugApp = packageName;
7055            mWaitForDebugger = waitForDebugger;
7056            mDebugTransient = !persistent;
7057            if (packageName != null) {
7058                final long origId = Binder.clearCallingIdentity();
7059                forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
7060                Binder.restoreCallingIdentity(origId);
7061            }
7062        }
7063    }
7064
7065    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7066        synchronized (this) {
7067            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7068            if (!isDebuggable) {
7069                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7070                    throw new SecurityException("Process not debuggable: " + app.packageName);
7071                }
7072            }
7073
7074            mOpenGlTraceApp = processName;
7075        }
7076    }
7077
7078    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7079            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7080        synchronized (this) {
7081            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7082            if (!isDebuggable) {
7083                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7084                    throw new SecurityException("Process not debuggable: " + app.packageName);
7085                }
7086            }
7087            mProfileApp = processName;
7088            mProfileFile = profileFile;
7089            if (mProfileFd != null) {
7090                try {
7091                    mProfileFd.close();
7092                } catch (IOException e) {
7093                }
7094                mProfileFd = null;
7095            }
7096            mProfileFd = profileFd;
7097            mProfileType = 0;
7098            mAutoStopProfiler = autoStopProfiler;
7099        }
7100    }
7101
7102    public void setAlwaysFinish(boolean enabled) {
7103        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7104                "setAlwaysFinish()");
7105
7106        Settings.System.putInt(
7107                mContext.getContentResolver(),
7108                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7109
7110        synchronized (this) {
7111            mAlwaysFinishActivities = enabled;
7112        }
7113    }
7114
7115    public void setActivityController(IActivityController controller) {
7116        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7117                "setActivityController()");
7118        synchronized (this) {
7119            mController = controller;
7120        }
7121    }
7122
7123    public boolean isUserAMonkey() {
7124        // For now the fact that there is a controller implies
7125        // we have a monkey.
7126        synchronized (this) {
7127            return mController != null;
7128        }
7129    }
7130
7131    public void registerProcessObserver(IProcessObserver observer) {
7132        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7133                "registerProcessObserver()");
7134        synchronized (this) {
7135            mProcessObservers.register(observer);
7136        }
7137    }
7138
7139    public void unregisterProcessObserver(IProcessObserver observer) {
7140        synchronized (this) {
7141            mProcessObservers.unregister(observer);
7142        }
7143    }
7144
7145    public void setImmersive(IBinder token, boolean immersive) {
7146        synchronized(this) {
7147            ActivityRecord r = mMainStack.isInStackLocked(token);
7148            if (r == null) {
7149                throw new IllegalArgumentException();
7150            }
7151            r.immersive = immersive;
7152        }
7153    }
7154
7155    public boolean isImmersive(IBinder token) {
7156        synchronized (this) {
7157            ActivityRecord r = mMainStack.isInStackLocked(token);
7158            if (r == null) {
7159                throw new IllegalArgumentException();
7160            }
7161            return r.immersive;
7162        }
7163    }
7164
7165    public boolean isTopActivityImmersive() {
7166        enforceNotIsolatedCaller("startActivity");
7167        synchronized (this) {
7168            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7169            return (r != null) ? r.immersive : false;
7170        }
7171    }
7172
7173    public final void enterSafeMode() {
7174        synchronized(this) {
7175            // It only makes sense to do this before the system is ready
7176            // and started launching other packages.
7177            if (!mSystemReady) {
7178                try {
7179                    AppGlobals.getPackageManager().enterSafeMode();
7180                } catch (RemoteException e) {
7181                }
7182            }
7183        }
7184    }
7185
7186    public final void showSafeModeOverlay() {
7187        View v = LayoutInflater.from(mContext).inflate(
7188                com.android.internal.R.layout.safe_mode, null);
7189        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7190        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7191        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7192        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7193        lp.gravity = Gravity.BOTTOM | Gravity.START;
7194        lp.format = v.getBackground().getOpacity();
7195        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7196                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7197        ((WindowManager)mContext.getSystemService(
7198                Context.WINDOW_SERVICE)).addView(v, lp);
7199    }
7200
7201    public void noteWakeupAlarm(IIntentSender sender) {
7202        if (!(sender instanceof PendingIntentRecord)) {
7203            return;
7204        }
7205        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7206        synchronized (stats) {
7207            if (mBatteryStatsService.isOnBattery()) {
7208                mBatteryStatsService.enforceCallingPermission();
7209                PendingIntentRecord rec = (PendingIntentRecord)sender;
7210                int MY_UID = Binder.getCallingUid();
7211                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7212                BatteryStatsImpl.Uid.Pkg pkg =
7213                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7214                pkg.incWakeupsLocked();
7215            }
7216        }
7217    }
7218
7219    public boolean killPids(int[] pids, String pReason, boolean secure) {
7220        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7221            throw new SecurityException("killPids only available to the system");
7222        }
7223        String reason = (pReason == null) ? "Unknown" : pReason;
7224        // XXX Note: don't acquire main activity lock here, because the window
7225        // manager calls in with its locks held.
7226
7227        boolean killed = false;
7228        synchronized (mPidsSelfLocked) {
7229            int[] types = new int[pids.length];
7230            int worstType = 0;
7231            for (int i=0; i<pids.length; i++) {
7232                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7233                if (proc != null) {
7234                    int type = proc.setAdj;
7235                    types[i] = type;
7236                    if (type > worstType) {
7237                        worstType = type;
7238                    }
7239                }
7240            }
7241
7242            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7243            // then constrain it so we will kill all hidden procs.
7244            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7245                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7246                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7247            }
7248
7249            // If this is not a secure call, don't let it kill processes that
7250            // are important.
7251            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7252                worstType = ProcessList.SERVICE_ADJ;
7253            }
7254
7255            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7256            for (int i=0; i<pids.length; i++) {
7257                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7258                if (proc == null) {
7259                    continue;
7260                }
7261                int adj = proc.setAdj;
7262                if (adj >= worstType && !proc.killedBackground) {
7263                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7264                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7265                            proc.processName, adj, reason);
7266                    killed = true;
7267                    proc.killedBackground = true;
7268                    Process.killProcessQuiet(pids[i]);
7269                }
7270            }
7271        }
7272        return killed;
7273    }
7274
7275    @Override
7276    public boolean killProcessesBelowForeground(String reason) {
7277        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7278            throw new SecurityException("killProcessesBelowForeground() only available to system");
7279        }
7280
7281        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7282    }
7283
7284    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7285        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7286            throw new SecurityException("killProcessesBelowAdj() only available to system");
7287        }
7288
7289        boolean killed = false;
7290        synchronized (mPidsSelfLocked) {
7291            final int size = mPidsSelfLocked.size();
7292            for (int i = 0; i < size; i++) {
7293                final int pid = mPidsSelfLocked.keyAt(i);
7294                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7295                if (proc == null) continue;
7296
7297                final int adj = proc.setAdj;
7298                if (adj > belowAdj && !proc.killedBackground) {
7299                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7300                    EventLog.writeEvent(
7301                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7302                    killed = true;
7303                    proc.killedBackground = true;
7304                    Process.killProcessQuiet(pid);
7305                }
7306            }
7307        }
7308        return killed;
7309    }
7310
7311    public final void startRunning(String pkg, String cls, String action,
7312            String data) {
7313        synchronized(this) {
7314            if (mStartRunning) {
7315                return;
7316            }
7317            mStartRunning = true;
7318            mTopComponent = pkg != null && cls != null
7319                    ? new ComponentName(pkg, cls) : null;
7320            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7321            mTopData = data;
7322            if (!mSystemReady) {
7323                return;
7324            }
7325        }
7326
7327        systemReady(null);
7328    }
7329
7330    private void retrieveSettings() {
7331        final ContentResolver resolver = mContext.getContentResolver();
7332        String debugApp = Settings.System.getString(
7333            resolver, Settings.System.DEBUG_APP);
7334        boolean waitForDebugger = Settings.System.getInt(
7335            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7336        boolean alwaysFinishActivities = Settings.System.getInt(
7337            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7338
7339        Configuration configuration = new Configuration();
7340        Settings.System.getConfiguration(resolver, configuration);
7341
7342        synchronized (this) {
7343            mDebugApp = mOrigDebugApp = debugApp;
7344            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7345            mAlwaysFinishActivities = alwaysFinishActivities;
7346            // This happens before any activities are started, so we can
7347            // change mConfiguration in-place.
7348            updateConfigurationLocked(configuration, null, false, true);
7349            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7350        }
7351    }
7352
7353    public boolean testIsSystemReady() {
7354        // no need to synchronize(this) just to read & return the value
7355        return mSystemReady;
7356    }
7357
7358    private static File getCalledPreBootReceiversFile() {
7359        File dataDir = Environment.getDataDirectory();
7360        File systemDir = new File(dataDir, "system");
7361        File fname = new File(systemDir, "called_pre_boots.dat");
7362        return fname;
7363    }
7364
7365    static final int LAST_DONE_VERSION = 10000;
7366
7367    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7368        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7369        File file = getCalledPreBootReceiversFile();
7370        FileInputStream fis = null;
7371        try {
7372            fis = new FileInputStream(file);
7373            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7374            int fvers = dis.readInt();
7375            if (fvers == LAST_DONE_VERSION) {
7376                String vers = dis.readUTF();
7377                String codename = dis.readUTF();
7378                String build = dis.readUTF();
7379                if (android.os.Build.VERSION.RELEASE.equals(vers)
7380                        && android.os.Build.VERSION.CODENAME.equals(codename)
7381                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7382                    int num = dis.readInt();
7383                    while (num > 0) {
7384                        num--;
7385                        String pkg = dis.readUTF();
7386                        String cls = dis.readUTF();
7387                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7388                    }
7389                }
7390            }
7391        } catch (FileNotFoundException e) {
7392        } catch (IOException e) {
7393            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7394        } finally {
7395            if (fis != null) {
7396                try {
7397                    fis.close();
7398                } catch (IOException e) {
7399                }
7400            }
7401        }
7402        return lastDoneReceivers;
7403    }
7404
7405    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7406        File file = getCalledPreBootReceiversFile();
7407        FileOutputStream fos = null;
7408        DataOutputStream dos = null;
7409        try {
7410            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7411            fos = new FileOutputStream(file);
7412            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7413            dos.writeInt(LAST_DONE_VERSION);
7414            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7415            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7416            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7417            dos.writeInt(list.size());
7418            for (int i=0; i<list.size(); i++) {
7419                dos.writeUTF(list.get(i).getPackageName());
7420                dos.writeUTF(list.get(i).getClassName());
7421            }
7422        } catch (IOException e) {
7423            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7424            file.delete();
7425        } finally {
7426            FileUtils.sync(fos);
7427            if (dos != null) {
7428                try {
7429                    dos.close();
7430                } catch (IOException e) {
7431                    // TODO Auto-generated catch block
7432                    e.printStackTrace();
7433                }
7434            }
7435        }
7436    }
7437
7438    public void systemReady(final Runnable goingCallback) {
7439        synchronized(this) {
7440            if (mSystemReady) {
7441                if (goingCallback != null) goingCallback.run();
7442                return;
7443            }
7444
7445            // Check to see if there are any update receivers to run.
7446            if (!mDidUpdate) {
7447                if (mWaitingUpdate) {
7448                    return;
7449                }
7450                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7451                List<ResolveInfo> ris = null;
7452                try {
7453                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7454                            intent, null, 0, 0);
7455                } catch (RemoteException e) {
7456                }
7457                if (ris != null) {
7458                    for (int i=ris.size()-1; i>=0; i--) {
7459                        if ((ris.get(i).activityInfo.applicationInfo.flags
7460                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7461                            ris.remove(i);
7462                        }
7463                    }
7464                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7465
7466                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7467
7468                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7469                    for (int i=0; i<ris.size(); i++) {
7470                        ActivityInfo ai = ris.get(i).activityInfo;
7471                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7472                        if (lastDoneReceivers.contains(comp)) {
7473                            ris.remove(i);
7474                            i--;
7475                        }
7476                    }
7477
7478                    for (int i=0; i<ris.size(); i++) {
7479                        ActivityInfo ai = ris.get(i).activityInfo;
7480                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7481                        doneReceivers.add(comp);
7482                        intent.setComponent(comp);
7483                        IIntentReceiver finisher = null;
7484                        if (i == ris.size()-1) {
7485                            finisher = new IIntentReceiver.Stub() {
7486                                public void performReceive(Intent intent, int resultCode,
7487                                        String data, Bundle extras, boolean ordered,
7488                                        boolean sticky) {
7489                                    // The raw IIntentReceiver interface is called
7490                                    // with the AM lock held, so redispatch to
7491                                    // execute our code without the lock.
7492                                    mHandler.post(new Runnable() {
7493                                        public void run() {
7494                                            synchronized (ActivityManagerService.this) {
7495                                                mDidUpdate = true;
7496                                            }
7497                                            writeLastDonePreBootReceivers(doneReceivers);
7498                                            showBootMessage(mContext.getText(
7499                                                    R.string.android_upgrading_complete),
7500                                                    false);
7501                                            systemReady(goingCallback);
7502                                        }
7503                                    });
7504                                }
7505                            };
7506                        }
7507                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7508                        /* TODO: Send this to all users */
7509                        broadcastIntentLocked(null, null, intent, null, finisher,
7510                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7511                                0 /* UserId zero */);
7512                        if (finisher != null) {
7513                            mWaitingUpdate = true;
7514                        }
7515                    }
7516                }
7517                if (mWaitingUpdate) {
7518                    return;
7519                }
7520                mDidUpdate = true;
7521            }
7522
7523            mSystemReady = true;
7524            if (!mStartRunning) {
7525                return;
7526            }
7527        }
7528
7529        ArrayList<ProcessRecord> procsToKill = null;
7530        synchronized(mPidsSelfLocked) {
7531            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7532                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7533                if (!isAllowedWhileBooting(proc.info)){
7534                    if (procsToKill == null) {
7535                        procsToKill = new ArrayList<ProcessRecord>();
7536                    }
7537                    procsToKill.add(proc);
7538                }
7539            }
7540        }
7541
7542        synchronized(this) {
7543            if (procsToKill != null) {
7544                for (int i=procsToKill.size()-1; i>=0; i--) {
7545                    ProcessRecord proc = procsToKill.get(i);
7546                    Slog.i(TAG, "Removing system update proc: " + proc);
7547                    removeProcessLocked(proc, true, false, "system update done");
7548                }
7549            }
7550
7551            // Now that we have cleaned up any update processes, we
7552            // are ready to start launching real processes and know that
7553            // we won't trample on them any more.
7554            mProcessesReady = true;
7555        }
7556
7557        Slog.i(TAG, "System now ready");
7558        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7559            SystemClock.uptimeMillis());
7560
7561        synchronized(this) {
7562            // Make sure we have no pre-ready processes sitting around.
7563
7564            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7565                ResolveInfo ri = mContext.getPackageManager()
7566                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7567                                STOCK_PM_FLAGS);
7568                CharSequence errorMsg = null;
7569                if (ri != null) {
7570                    ActivityInfo ai = ri.activityInfo;
7571                    ApplicationInfo app = ai.applicationInfo;
7572                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7573                        mTopAction = Intent.ACTION_FACTORY_TEST;
7574                        mTopData = null;
7575                        mTopComponent = new ComponentName(app.packageName,
7576                                ai.name);
7577                    } else {
7578                        errorMsg = mContext.getResources().getText(
7579                                com.android.internal.R.string.factorytest_not_system);
7580                    }
7581                } else {
7582                    errorMsg = mContext.getResources().getText(
7583                            com.android.internal.R.string.factorytest_no_action);
7584                }
7585                if (errorMsg != null) {
7586                    mTopAction = null;
7587                    mTopData = null;
7588                    mTopComponent = null;
7589                    Message msg = Message.obtain();
7590                    msg.what = SHOW_FACTORY_ERROR_MSG;
7591                    msg.getData().putCharSequence("msg", errorMsg);
7592                    mHandler.sendMessage(msg);
7593                }
7594            }
7595        }
7596
7597        retrieveSettings();
7598
7599        if (goingCallback != null) goingCallback.run();
7600
7601        synchronized (this) {
7602            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7603                try {
7604                    List apps = AppGlobals.getPackageManager().
7605                        getPersistentApplications(STOCK_PM_FLAGS);
7606                    if (apps != null) {
7607                        int N = apps.size();
7608                        int i;
7609                        for (i=0; i<N; i++) {
7610                            ApplicationInfo info
7611                                = (ApplicationInfo)apps.get(i);
7612                            if (info != null &&
7613                                    !info.packageName.equals("android")) {
7614                                addAppLocked(info, false);
7615                            }
7616                        }
7617                    }
7618                } catch (RemoteException ex) {
7619                    // pm is in same process, this will never happen.
7620                }
7621            }
7622
7623            // Start up initial activity.
7624            mBooting = true;
7625
7626            try {
7627                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7628                    Message msg = Message.obtain();
7629                    msg.what = SHOW_UID_ERROR_MSG;
7630                    mHandler.sendMessage(msg);
7631                }
7632            } catch (RemoteException e) {
7633            }
7634
7635            mMainStack.resumeTopActivityLocked(null);
7636        }
7637    }
7638
7639    private boolean makeAppCrashingLocked(ProcessRecord app,
7640            String shortMsg, String longMsg, String stackTrace) {
7641        app.crashing = true;
7642        app.crashingReport = generateProcessError(app,
7643                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7644        startAppProblemLocked(app);
7645        app.stopFreezingAllLocked();
7646        return handleAppCrashLocked(app);
7647    }
7648
7649    private void makeAppNotRespondingLocked(ProcessRecord app,
7650            String activity, String shortMsg, String longMsg) {
7651        app.notResponding = true;
7652        app.notRespondingReport = generateProcessError(app,
7653                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7654                activity, shortMsg, longMsg, null);
7655        startAppProblemLocked(app);
7656        app.stopFreezingAllLocked();
7657    }
7658
7659    /**
7660     * Generate a process error record, suitable for attachment to a ProcessRecord.
7661     *
7662     * @param app The ProcessRecord in which the error occurred.
7663     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7664     *                      ActivityManager.AppErrorStateInfo
7665     * @param activity The activity associated with the crash, if known.
7666     * @param shortMsg Short message describing the crash.
7667     * @param longMsg Long message describing the crash.
7668     * @param stackTrace Full crash stack trace, may be null.
7669     *
7670     * @return Returns a fully-formed AppErrorStateInfo record.
7671     */
7672    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7673            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7674        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7675
7676        report.condition = condition;
7677        report.processName = app.processName;
7678        report.pid = app.pid;
7679        report.uid = app.info.uid;
7680        report.tag = activity;
7681        report.shortMsg = shortMsg;
7682        report.longMsg = longMsg;
7683        report.stackTrace = stackTrace;
7684
7685        return report;
7686    }
7687
7688    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7689        synchronized (this) {
7690            app.crashing = false;
7691            app.crashingReport = null;
7692            app.notResponding = false;
7693            app.notRespondingReport = null;
7694            if (app.anrDialog == fromDialog) {
7695                app.anrDialog = null;
7696            }
7697            if (app.waitDialog == fromDialog) {
7698                app.waitDialog = null;
7699            }
7700            if (app.pid > 0 && app.pid != MY_PID) {
7701                handleAppCrashLocked(app);
7702                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7703                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7704                        app.processName, app.setAdj, "user's request after error");
7705                Process.killProcessQuiet(app.pid);
7706            }
7707        }
7708    }
7709
7710    private boolean handleAppCrashLocked(ProcessRecord app) {
7711        if (mHeadless) {
7712            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7713            return false;
7714        }
7715        long now = SystemClock.uptimeMillis();
7716
7717        Long crashTime;
7718        if (!app.isolated) {
7719            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7720        } else {
7721            crashTime = null;
7722        }
7723        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7724            // This process loses!
7725            Slog.w(TAG, "Process " + app.info.processName
7726                    + " has crashed too many times: killing!");
7727            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7728                    app.info.processName, app.uid);
7729            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7730                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7731                if (r.app == app) {
7732                    Slog.w(TAG, "  Force finishing activity "
7733                        + r.intent.getComponent().flattenToShortString());
7734                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7735                }
7736            }
7737            if (!app.persistent) {
7738                // We don't want to start this process again until the user
7739                // explicitly does so...  but for persistent process, we really
7740                // need to keep it running.  If a persistent process is actually
7741                // repeatedly crashing, then badness for everyone.
7742                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7743                        app.info.processName);
7744                if (!app.isolated) {
7745                    // XXX We don't have a way to mark isolated processes
7746                    // as bad, since they don't have a peristent identity.
7747                    mBadProcesses.put(app.info.processName, app.uid, now);
7748                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7749                }
7750                app.bad = true;
7751                app.removed = true;
7752                // Don't let services in this process be restarted and potentially
7753                // annoy the user repeatedly.  Unless it is persistent, since those
7754                // processes run critical code.
7755                removeProcessLocked(app, false, false, "crash");
7756                mMainStack.resumeTopActivityLocked(null);
7757                return false;
7758            }
7759            mMainStack.resumeTopActivityLocked(null);
7760        } else {
7761            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7762            if (r != null && r.app == app) {
7763                // If the top running activity is from this crashing
7764                // process, then terminate it to avoid getting in a loop.
7765                Slog.w(TAG, "  Force finishing activity "
7766                        + r.intent.getComponent().flattenToShortString());
7767                int index = mMainStack.indexOfActivityLocked(r);
7768                r.stack.finishActivityLocked(r, index,
7769                        Activity.RESULT_CANCELED, null, "crashed");
7770                // Also terminate any activities below it that aren't yet
7771                // stopped, to avoid a situation where one will get
7772                // re-start our crashing activity once it gets resumed again.
7773                index--;
7774                if (index >= 0) {
7775                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7776                    if (r.state == ActivityState.RESUMED
7777                            || r.state == ActivityState.PAUSING
7778                            || r.state == ActivityState.PAUSED) {
7779                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7780                            Slog.w(TAG, "  Force finishing activity "
7781                                    + r.intent.getComponent().flattenToShortString());
7782                            r.stack.finishActivityLocked(r, index,
7783                                    Activity.RESULT_CANCELED, null, "crashed");
7784                        }
7785                    }
7786                }
7787            }
7788        }
7789
7790        // Bump up the crash count of any services currently running in the proc.
7791        if (app.services.size() != 0) {
7792            // Any services running in the application need to be placed
7793            // back in the pending list.
7794            Iterator<ServiceRecord> it = app.services.iterator();
7795            while (it.hasNext()) {
7796                ServiceRecord sr = it.next();
7797                sr.crashCount++;
7798            }
7799        }
7800
7801        // If the crashing process is what we consider to be the "home process" and it has been
7802        // replaced by a third-party app, clear the package preferred activities from packages
7803        // with a home activity running in the process to prevent a repeatedly crashing app
7804        // from blocking the user to manually clear the list.
7805        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7806                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7807            Iterator it = mHomeProcess.activities.iterator();
7808            while (it.hasNext()) {
7809                ActivityRecord r = (ActivityRecord)it.next();
7810                if (r.isHomeActivity) {
7811                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7812                    try {
7813                        ActivityThread.getPackageManager()
7814                                .clearPackagePreferredActivities(r.packageName);
7815                    } catch (RemoteException c) {
7816                        // pm is in same process, this will never happen.
7817                    }
7818                }
7819            }
7820        }
7821
7822        if (!app.isolated) {
7823            // XXX Can't keep track of crash times for isolated processes,
7824            // because they don't have a perisistent identity.
7825            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7826        }
7827
7828        return true;
7829    }
7830
7831    void startAppProblemLocked(ProcessRecord app) {
7832        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7833                mContext, app.info.packageName, app.info.flags);
7834        skipCurrentReceiverLocked(app);
7835    }
7836
7837    void skipCurrentReceiverLocked(ProcessRecord app) {
7838        for (BroadcastQueue queue : mBroadcastQueues) {
7839            queue.skipCurrentReceiverLocked(app);
7840        }
7841    }
7842
7843    /**
7844     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7845     * The application process will exit immediately after this call returns.
7846     * @param app object of the crashing app, null for the system server
7847     * @param crashInfo describing the exception
7848     */
7849    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7850        ProcessRecord r = findAppProcess(app, "Crash");
7851        final String processName = app == null ? "system_server"
7852                : (r == null ? "unknown" : r.processName);
7853
7854        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7855                processName,
7856                r == null ? -1 : r.info.flags,
7857                crashInfo.exceptionClassName,
7858                crashInfo.exceptionMessage,
7859                crashInfo.throwFileName,
7860                crashInfo.throwLineNumber);
7861
7862        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7863
7864        crashApplication(r, crashInfo);
7865    }
7866
7867    public void handleApplicationStrictModeViolation(
7868            IBinder app,
7869            int violationMask,
7870            StrictMode.ViolationInfo info) {
7871        ProcessRecord r = findAppProcess(app, "StrictMode");
7872        if (r == null) {
7873            return;
7874        }
7875
7876        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7877            Integer stackFingerprint = info.hashCode();
7878            boolean logIt = true;
7879            synchronized (mAlreadyLoggedViolatedStacks) {
7880                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7881                    logIt = false;
7882                    // TODO: sub-sample into EventLog for these, with
7883                    // the info.durationMillis?  Then we'd get
7884                    // the relative pain numbers, without logging all
7885                    // the stack traces repeatedly.  We'd want to do
7886                    // likewise in the client code, which also does
7887                    // dup suppression, before the Binder call.
7888                } else {
7889                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7890                        mAlreadyLoggedViolatedStacks.clear();
7891                    }
7892                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7893                }
7894            }
7895            if (logIt) {
7896                logStrictModeViolationToDropBox(r, info);
7897            }
7898        }
7899
7900        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7901            AppErrorResult result = new AppErrorResult();
7902            synchronized (this) {
7903                final long origId = Binder.clearCallingIdentity();
7904
7905                Message msg = Message.obtain();
7906                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7907                HashMap<String, Object> data = new HashMap<String, Object>();
7908                data.put("result", result);
7909                data.put("app", r);
7910                data.put("violationMask", violationMask);
7911                data.put("info", info);
7912                msg.obj = data;
7913                mHandler.sendMessage(msg);
7914
7915                Binder.restoreCallingIdentity(origId);
7916            }
7917            int res = result.get();
7918            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7919        }
7920    }
7921
7922    // Depending on the policy in effect, there could be a bunch of
7923    // these in quick succession so we try to batch these together to
7924    // minimize disk writes, number of dropbox entries, and maximize
7925    // compression, by having more fewer, larger records.
7926    private void logStrictModeViolationToDropBox(
7927            ProcessRecord process,
7928            StrictMode.ViolationInfo info) {
7929        if (info == null) {
7930            return;
7931        }
7932        final boolean isSystemApp = process == null ||
7933                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7934                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7935        final String processName = process == null ? "unknown" : process.processName;
7936        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7937        final DropBoxManager dbox = (DropBoxManager)
7938                mContext.getSystemService(Context.DROPBOX_SERVICE);
7939
7940        // Exit early if the dropbox isn't configured to accept this report type.
7941        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7942
7943        boolean bufferWasEmpty;
7944        boolean needsFlush;
7945        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7946        synchronized (sb) {
7947            bufferWasEmpty = sb.length() == 0;
7948            appendDropBoxProcessHeaders(process, processName, sb);
7949            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7950            sb.append("System-App: ").append(isSystemApp).append("\n");
7951            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7952            if (info.violationNumThisLoop != 0) {
7953                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7954            }
7955            if (info.numAnimationsRunning != 0) {
7956                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7957            }
7958            if (info.broadcastIntentAction != null) {
7959                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7960            }
7961            if (info.durationMillis != -1) {
7962                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
7963            }
7964            if (info.numInstances != -1) {
7965                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7966            }
7967            if (info.tags != null) {
7968                for (String tag : info.tags) {
7969                    sb.append("Span-Tag: ").append(tag).append("\n");
7970                }
7971            }
7972            sb.append("\n");
7973            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7974                sb.append(info.crashInfo.stackTrace);
7975            }
7976            sb.append("\n");
7977
7978            // Only buffer up to ~64k.  Various logging bits truncate
7979            // things at 128k.
7980            needsFlush = (sb.length() > 64 * 1024);
7981        }
7982
7983        // Flush immediately if the buffer's grown too large, or this
7984        // is a non-system app.  Non-system apps are isolated with a
7985        // different tag & policy and not batched.
7986        //
7987        // Batching is useful during internal testing with
7988        // StrictMode settings turned up high.  Without batching,
7989        // thousands of separate files could be created on boot.
7990        if (!isSystemApp || needsFlush) {
7991            new Thread("Error dump: " + dropboxTag) {
7992                @Override
7993                public void run() {
7994                    String report;
7995                    synchronized (sb) {
7996                        report = sb.toString();
7997                        sb.delete(0, sb.length());
7998                        sb.trimToSize();
7999                    }
8000                    if (report.length() != 0) {
8001                        dbox.addText(dropboxTag, report);
8002                    }
8003                }
8004            }.start();
8005            return;
8006        }
8007
8008        // System app batching:
8009        if (!bufferWasEmpty) {
8010            // An existing dropbox-writing thread is outstanding, so
8011            // we don't need to start it up.  The existing thread will
8012            // catch the buffer appends we just did.
8013            return;
8014        }
8015
8016        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8017        // (After this point, we shouldn't access AMS internal data structures.)
8018        new Thread("Error dump: " + dropboxTag) {
8019            @Override
8020            public void run() {
8021                // 5 second sleep to let stacks arrive and be batched together
8022                try {
8023                    Thread.sleep(5000);  // 5 seconds
8024                } catch (InterruptedException e) {}
8025
8026                String errorReport;
8027                synchronized (mStrictModeBuffer) {
8028                    errorReport = mStrictModeBuffer.toString();
8029                    if (errorReport.length() == 0) {
8030                        return;
8031                    }
8032                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8033                    mStrictModeBuffer.trimToSize();
8034                }
8035                dbox.addText(dropboxTag, errorReport);
8036            }
8037        }.start();
8038    }
8039
8040    /**
8041     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8042     * @param app object of the crashing app, null for the system server
8043     * @param tag reported by the caller
8044     * @param crashInfo describing the context of the error
8045     * @return true if the process should exit immediately (WTF is fatal)
8046     */
8047    public boolean handleApplicationWtf(IBinder app, String tag,
8048            ApplicationErrorReport.CrashInfo crashInfo) {
8049        ProcessRecord r = findAppProcess(app, "WTF");
8050        final String processName = app == null ? "system_server"
8051                : (r == null ? "unknown" : r.processName);
8052
8053        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8054                processName,
8055                r == null ? -1 : r.info.flags,
8056                tag, crashInfo.exceptionMessage);
8057
8058        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8059
8060        if (r != null && r.pid != Process.myPid() &&
8061                Settings.Secure.getInt(mContext.getContentResolver(),
8062                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8063            crashApplication(r, crashInfo);
8064            return true;
8065        } else {
8066            return false;
8067        }
8068    }
8069
8070    /**
8071     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8072     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8073     */
8074    private ProcessRecord findAppProcess(IBinder app, String reason) {
8075        if (app == null) {
8076            return null;
8077        }
8078
8079        synchronized (this) {
8080            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8081                final int NA = apps.size();
8082                for (int ia=0; ia<NA; ia++) {
8083                    ProcessRecord p = apps.valueAt(ia);
8084                    if (p.thread != null && p.thread.asBinder() == app) {
8085                        return p;
8086                    }
8087                }
8088            }
8089
8090            Slog.w(TAG, "Can't find mystery application for " + reason
8091                    + " from pid=" + Binder.getCallingPid()
8092                    + " uid=" + Binder.getCallingUid() + ": " + app);
8093            return null;
8094        }
8095    }
8096
8097    /**
8098     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8099     * to append various headers to the dropbox log text.
8100     */
8101    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8102            StringBuilder sb) {
8103        // Watchdog thread ends up invoking this function (with
8104        // a null ProcessRecord) to add the stack file to dropbox.
8105        // Do not acquire a lock on this (am) in such cases, as it
8106        // could cause a potential deadlock, if and when watchdog
8107        // is invoked due to unavailability of lock on am and it
8108        // would prevent watchdog from killing system_server.
8109        if (process == null) {
8110            sb.append("Process: ").append(processName).append("\n");
8111            return;
8112        }
8113        // Note: ProcessRecord 'process' is guarded by the service
8114        // instance.  (notably process.pkgList, which could otherwise change
8115        // concurrently during execution of this method)
8116        synchronized (this) {
8117            sb.append("Process: ").append(processName).append("\n");
8118            int flags = process.info.flags;
8119            IPackageManager pm = AppGlobals.getPackageManager();
8120            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8121            for (String pkg : process.pkgList) {
8122                sb.append("Package: ").append(pkg);
8123                try {
8124                    PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
8125                    if (pi != null) {
8126                        sb.append(" v").append(pi.versionCode);
8127                        if (pi.versionName != null) {
8128                            sb.append(" (").append(pi.versionName).append(")");
8129                        }
8130                    }
8131                } catch (RemoteException e) {
8132                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8133                }
8134                sb.append("\n");
8135            }
8136        }
8137    }
8138
8139    private static String processClass(ProcessRecord process) {
8140        if (process == null || process.pid == MY_PID) {
8141            return "system_server";
8142        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8143            return "system_app";
8144        } else {
8145            return "data_app";
8146        }
8147    }
8148
8149    /**
8150     * Write a description of an error (crash, WTF, ANR) to the drop box.
8151     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8152     * @param process which caused the error, null means the system server
8153     * @param activity which triggered the error, null if unknown
8154     * @param parent activity related to the error, null if unknown
8155     * @param subject line related to the error, null if absent
8156     * @param report in long form describing the error, null if absent
8157     * @param logFile to include in the report, null if none
8158     * @param crashInfo giving an application stack trace, null if absent
8159     */
8160    public void addErrorToDropBox(String eventType,
8161            ProcessRecord process, String processName, ActivityRecord activity,
8162            ActivityRecord parent, String subject,
8163            final String report, final File logFile,
8164            final ApplicationErrorReport.CrashInfo crashInfo) {
8165        // NOTE -- this must never acquire the ActivityManagerService lock,
8166        // otherwise the watchdog may be prevented from resetting the system.
8167
8168        final String dropboxTag = processClass(process) + "_" + eventType;
8169        final DropBoxManager dbox = (DropBoxManager)
8170                mContext.getSystemService(Context.DROPBOX_SERVICE);
8171
8172        // Exit early if the dropbox isn't configured to accept this report type.
8173        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8174
8175        final StringBuilder sb = new StringBuilder(1024);
8176        appendDropBoxProcessHeaders(process, processName, sb);
8177        if (activity != null) {
8178            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8179        }
8180        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8181            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8182        }
8183        if (parent != null && parent != activity) {
8184            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8185        }
8186        if (subject != null) {
8187            sb.append("Subject: ").append(subject).append("\n");
8188        }
8189        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8190        if (Debug.isDebuggerConnected()) {
8191            sb.append("Debugger: Connected\n");
8192        }
8193        sb.append("\n");
8194
8195        // Do the rest in a worker thread to avoid blocking the caller on I/O
8196        // (After this point, we shouldn't access AMS internal data structures.)
8197        Thread worker = new Thread("Error dump: " + dropboxTag) {
8198            @Override
8199            public void run() {
8200                if (report != null) {
8201                    sb.append(report);
8202                }
8203                if (logFile != null) {
8204                    try {
8205                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8206                    } catch (IOException e) {
8207                        Slog.e(TAG, "Error reading " + logFile, e);
8208                    }
8209                }
8210                if (crashInfo != null && crashInfo.stackTrace != null) {
8211                    sb.append(crashInfo.stackTrace);
8212                }
8213
8214                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8215                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8216                if (lines > 0) {
8217                    sb.append("\n");
8218
8219                    // Merge several logcat streams, and take the last N lines
8220                    InputStreamReader input = null;
8221                    try {
8222                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8223                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8224                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8225
8226                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8227                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8228                        input = new InputStreamReader(logcat.getInputStream());
8229
8230                        int num;
8231                        char[] buf = new char[8192];
8232                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8233                    } catch (IOException e) {
8234                        Slog.e(TAG, "Error running logcat", e);
8235                    } finally {
8236                        if (input != null) try { input.close(); } catch (IOException e) {}
8237                    }
8238                }
8239
8240                dbox.addText(dropboxTag, sb.toString());
8241            }
8242        };
8243
8244        if (process == null) {
8245            // If process is null, we are being called from some internal code
8246            // and may be about to die -- run this synchronously.
8247            worker.run();
8248        } else {
8249            worker.start();
8250        }
8251    }
8252
8253    /**
8254     * Bring up the "unexpected error" dialog box for a crashing app.
8255     * Deal with edge cases (intercepts from instrumented applications,
8256     * ActivityController, error intent receivers, that sort of thing).
8257     * @param r the application crashing
8258     * @param crashInfo describing the failure
8259     */
8260    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8261        long timeMillis = System.currentTimeMillis();
8262        String shortMsg = crashInfo.exceptionClassName;
8263        String longMsg = crashInfo.exceptionMessage;
8264        String stackTrace = crashInfo.stackTrace;
8265        if (shortMsg != null && longMsg != null) {
8266            longMsg = shortMsg + ": " + longMsg;
8267        } else if (shortMsg != null) {
8268            longMsg = shortMsg;
8269        }
8270
8271        AppErrorResult result = new AppErrorResult();
8272        synchronized (this) {
8273            if (mController != null) {
8274                try {
8275                    String name = r != null ? r.processName : null;
8276                    int pid = r != null ? r.pid : Binder.getCallingPid();
8277                    if (!mController.appCrashed(name, pid,
8278                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8279                        Slog.w(TAG, "Force-killing crashed app " + name
8280                                + " at watcher's request");
8281                        Process.killProcess(pid);
8282                        return;
8283                    }
8284                } catch (RemoteException e) {
8285                    mController = null;
8286                }
8287            }
8288
8289            final long origId = Binder.clearCallingIdentity();
8290
8291            // If this process is running instrumentation, finish it.
8292            if (r != null && r.instrumentationClass != null) {
8293                Slog.w(TAG, "Error in app " + r.processName
8294                      + " running instrumentation " + r.instrumentationClass + ":");
8295                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8296                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8297                Bundle info = new Bundle();
8298                info.putString("shortMsg", shortMsg);
8299                info.putString("longMsg", longMsg);
8300                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8301                Binder.restoreCallingIdentity(origId);
8302                return;
8303            }
8304
8305            // If we can't identify the process or it's already exceeded its crash quota,
8306            // quit right away without showing a crash dialog.
8307            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8308                Binder.restoreCallingIdentity(origId);
8309                return;
8310            }
8311
8312            Message msg = Message.obtain();
8313            msg.what = SHOW_ERROR_MSG;
8314            HashMap data = new HashMap();
8315            data.put("result", result);
8316            data.put("app", r);
8317            msg.obj = data;
8318            mHandler.sendMessage(msg);
8319
8320            Binder.restoreCallingIdentity(origId);
8321        }
8322
8323        int res = result.get();
8324
8325        Intent appErrorIntent = null;
8326        synchronized (this) {
8327            if (r != null && !r.isolated) {
8328                // XXX Can't keep track of crash time for isolated processes,
8329                // since they don't have a persistent identity.
8330                mProcessCrashTimes.put(r.info.processName, r.uid,
8331                        SystemClock.uptimeMillis());
8332            }
8333            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8334                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8335            }
8336        }
8337
8338        if (appErrorIntent != null) {
8339            try {
8340                mContext.startActivity(appErrorIntent);
8341            } catch (ActivityNotFoundException e) {
8342                Slog.w(TAG, "bug report receiver dissappeared", e);
8343            }
8344        }
8345    }
8346
8347    Intent createAppErrorIntentLocked(ProcessRecord r,
8348            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8349        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8350        if (report == null) {
8351            return null;
8352        }
8353        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8354        result.setComponent(r.errorReportReceiver);
8355        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8356        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8357        return result;
8358    }
8359
8360    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8361            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8362        if (r.errorReportReceiver == null) {
8363            return null;
8364        }
8365
8366        if (!r.crashing && !r.notResponding) {
8367            return null;
8368        }
8369
8370        ApplicationErrorReport report = new ApplicationErrorReport();
8371        report.packageName = r.info.packageName;
8372        report.installerPackageName = r.errorReportReceiver.getPackageName();
8373        report.processName = r.processName;
8374        report.time = timeMillis;
8375        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8376
8377        if (r.crashing) {
8378            report.type = ApplicationErrorReport.TYPE_CRASH;
8379            report.crashInfo = crashInfo;
8380        } else if (r.notResponding) {
8381            report.type = ApplicationErrorReport.TYPE_ANR;
8382            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8383
8384            report.anrInfo.activity = r.notRespondingReport.tag;
8385            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8386            report.anrInfo.info = r.notRespondingReport.longMsg;
8387        }
8388
8389        return report;
8390    }
8391
8392    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8393        enforceNotIsolatedCaller("getProcessesInErrorState");
8394        // assume our apps are happy - lazy create the list
8395        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8396
8397        final boolean allUsers = ActivityManager.checkUidPermission(
8398                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8399                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8400        int userId = UserHandle.getUserId(Binder.getCallingUid());
8401
8402        synchronized (this) {
8403
8404            // iterate across all processes
8405            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8406                ProcessRecord app = mLruProcesses.get(i);
8407                if (!allUsers && app.userId != userId) {
8408                    continue;
8409                }
8410                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8411                    // This one's in trouble, so we'll generate a report for it
8412                    // crashes are higher priority (in case there's a crash *and* an anr)
8413                    ActivityManager.ProcessErrorStateInfo report = null;
8414                    if (app.crashing) {
8415                        report = app.crashingReport;
8416                    } else if (app.notResponding) {
8417                        report = app.notRespondingReport;
8418                    }
8419
8420                    if (report != null) {
8421                        if (errList == null) {
8422                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8423                        }
8424                        errList.add(report);
8425                    } else {
8426                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8427                                " crashing = " + app.crashing +
8428                                " notResponding = " + app.notResponding);
8429                    }
8430                }
8431            }
8432        }
8433
8434        return errList;
8435    }
8436
8437    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8438        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8439            if (currApp != null) {
8440                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8441            }
8442            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8443        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8444            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8445        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8446            if (currApp != null) {
8447                currApp.lru = 0;
8448            }
8449            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8450        } else if (adj >= ProcessList.SERVICE_ADJ) {
8451            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8452        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8453            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8454        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8455            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8456        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8457            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8458        } else {
8459            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8460        }
8461    }
8462
8463    private void fillInProcMemInfo(ProcessRecord app,
8464            ActivityManager.RunningAppProcessInfo outInfo) {
8465        outInfo.pid = app.pid;
8466        outInfo.uid = app.info.uid;
8467        if (mHeavyWeightProcess == app) {
8468            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8469        }
8470        if (app.persistent) {
8471            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8472        }
8473        if (app.hasActivities) {
8474            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8475        }
8476        outInfo.lastTrimLevel = app.trimMemoryLevel;
8477        int adj = app.curAdj;
8478        outInfo.importance = oomAdjToImportance(adj, outInfo);
8479        outInfo.importanceReasonCode = app.adjTypeCode;
8480    }
8481
8482    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8483        enforceNotIsolatedCaller("getRunningAppProcesses");
8484        // Lazy instantiation of list
8485        List<ActivityManager.RunningAppProcessInfo> runList = null;
8486        final boolean allUsers = ActivityManager.checkUidPermission(
8487                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8488                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8489        int userId = UserHandle.getUserId(Binder.getCallingUid());
8490        synchronized (this) {
8491            // Iterate across all processes
8492            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8493                ProcessRecord app = mLruProcesses.get(i);
8494                if (!allUsers && app.userId != userId) {
8495                    continue;
8496                }
8497                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8498                    // Generate process state info for running application
8499                    ActivityManager.RunningAppProcessInfo currApp =
8500                        new ActivityManager.RunningAppProcessInfo(app.processName,
8501                                app.pid, app.getPackageList());
8502                    fillInProcMemInfo(app, currApp);
8503                    if (app.adjSource instanceof ProcessRecord) {
8504                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8505                        currApp.importanceReasonImportance = oomAdjToImportance(
8506                                app.adjSourceOom, null);
8507                    } else if (app.adjSource instanceof ActivityRecord) {
8508                        ActivityRecord r = (ActivityRecord)app.adjSource;
8509                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8510                    }
8511                    if (app.adjTarget instanceof ComponentName) {
8512                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8513                    }
8514                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8515                    //        + " lru=" + currApp.lru);
8516                    if (runList == null) {
8517                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8518                    }
8519                    runList.add(currApp);
8520                }
8521            }
8522        }
8523        return runList;
8524    }
8525
8526    public List<ApplicationInfo> getRunningExternalApplications() {
8527        enforceNotIsolatedCaller("getRunningExternalApplications");
8528        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8529        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8530        if (runningApps != null && runningApps.size() > 0) {
8531            Set<String> extList = new HashSet<String>();
8532            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8533                if (app.pkgList != null) {
8534                    for (String pkg : app.pkgList) {
8535                        extList.add(pkg);
8536                    }
8537                }
8538            }
8539            IPackageManager pm = AppGlobals.getPackageManager();
8540            for (String pkg : extList) {
8541                try {
8542                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8543                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8544                        retList.add(info);
8545                    }
8546                } catch (RemoteException e) {
8547                }
8548            }
8549        }
8550        return retList;
8551    }
8552
8553    @Override
8554    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8555        enforceNotIsolatedCaller("getMyMemoryState");
8556        synchronized (this) {
8557            ProcessRecord proc;
8558            synchronized (mPidsSelfLocked) {
8559                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8560            }
8561            fillInProcMemInfo(proc, outInfo);
8562        }
8563    }
8564
8565    @Override
8566    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8567        if (checkCallingPermission(android.Manifest.permission.DUMP)
8568                != PackageManager.PERMISSION_GRANTED) {
8569            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8570                    + Binder.getCallingPid()
8571                    + ", uid=" + Binder.getCallingUid()
8572                    + " without permission "
8573                    + android.Manifest.permission.DUMP);
8574            return;
8575        }
8576
8577        boolean dumpAll = false;
8578        boolean dumpClient = false;
8579        String dumpPackage = null;
8580
8581        int opti = 0;
8582        while (opti < args.length) {
8583            String opt = args[opti];
8584            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8585                break;
8586            }
8587            opti++;
8588            if ("-a".equals(opt)) {
8589                dumpAll = true;
8590            } else if ("-c".equals(opt)) {
8591                dumpClient = true;
8592            } else if ("-h".equals(opt)) {
8593                pw.println("Activity manager dump options:");
8594                pw.println("  [-a] [-c] [-h] [cmd] ...");
8595                pw.println("  cmd may be one of:");
8596                pw.println("    a[ctivities]: activity stack state");
8597                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8598                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8599                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8600                pw.println("    o[om]: out of memory management");
8601                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8602                pw.println("    provider [COMP_SPEC]: provider client-side state");
8603                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8604                pw.println("    service [COMP_SPEC]: service client-side state");
8605                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8606                pw.println("    all: dump all activities");
8607                pw.println("    top: dump the top activity");
8608                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8609                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8610                pw.println("    a partial substring in a component name, a");
8611                pw.println("    hex object identifier.");
8612                pw.println("  -a: include all available server state.");
8613                pw.println("  -c: include client state.");
8614                return;
8615            } else {
8616                pw.println("Unknown argument: " + opt + "; use -h for help");
8617            }
8618        }
8619
8620        long origId = Binder.clearCallingIdentity();
8621        boolean more = false;
8622        // Is the caller requesting to dump a particular piece of data?
8623        if (opti < args.length) {
8624            String cmd = args[opti];
8625            opti++;
8626            if ("activities".equals(cmd) || "a".equals(cmd)) {
8627                synchronized (this) {
8628                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8629                }
8630            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8631                String[] newArgs;
8632                String name;
8633                if (opti >= args.length) {
8634                    name = null;
8635                    newArgs = EMPTY_STRING_ARRAY;
8636                } else {
8637                    name = args[opti];
8638                    opti++;
8639                    newArgs = new String[args.length - opti];
8640                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8641                            args.length - opti);
8642                }
8643                synchronized (this) {
8644                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8645                }
8646            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8647                String[] newArgs;
8648                String name;
8649                if (opti >= args.length) {
8650                    name = null;
8651                    newArgs = EMPTY_STRING_ARRAY;
8652                } else {
8653                    name = args[opti];
8654                    opti++;
8655                    newArgs = new String[args.length - opti];
8656                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8657                            args.length - opti);
8658                }
8659                synchronized (this) {
8660                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8661                }
8662            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8663                String[] newArgs;
8664                String name;
8665                if (opti >= args.length) {
8666                    name = null;
8667                    newArgs = EMPTY_STRING_ARRAY;
8668                } else {
8669                    name = args[opti];
8670                    opti++;
8671                    newArgs = new String[args.length - opti];
8672                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8673                            args.length - opti);
8674                }
8675                synchronized (this) {
8676                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8677                }
8678            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8679                synchronized (this) {
8680                    dumpOomLocked(fd, pw, args, opti, true);
8681                }
8682            } else if ("provider".equals(cmd)) {
8683                String[] newArgs;
8684                String name;
8685                if (opti >= args.length) {
8686                    name = null;
8687                    newArgs = EMPTY_STRING_ARRAY;
8688                } else {
8689                    name = args[opti];
8690                    opti++;
8691                    newArgs = new String[args.length - opti];
8692                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8693                }
8694                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8695                    pw.println("No providers match: " + name);
8696                    pw.println("Use -h for help.");
8697                }
8698            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8699                synchronized (this) {
8700                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8701                }
8702            } else if ("service".equals(cmd)) {
8703                String[] newArgs;
8704                String name;
8705                if (opti >= args.length) {
8706                    name = null;
8707                    newArgs = EMPTY_STRING_ARRAY;
8708                } else {
8709                    name = args[opti];
8710                    opti++;
8711                    newArgs = new String[args.length - opti];
8712                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8713                            args.length - opti);
8714                }
8715                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8716                    pw.println("No services match: " + name);
8717                    pw.println("Use -h for help.");
8718                }
8719            } else if ("package".equals(cmd)) {
8720                String[] newArgs;
8721                if (opti >= args.length) {
8722                    pw.println("package: no package name specified");
8723                    pw.println("Use -h for help.");
8724                } else {
8725                    dumpPackage = args[opti];
8726                    opti++;
8727                    newArgs = new String[args.length - opti];
8728                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8729                            args.length - opti);
8730                    args = newArgs;
8731                    opti = 0;
8732                    more = true;
8733                }
8734            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8735                synchronized (this) {
8736                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8737                }
8738            } else {
8739                // Dumping a single activity?
8740                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8741                    pw.println("Bad activity command, or no activities match: " + cmd);
8742                    pw.println("Use -h for help.");
8743                }
8744            }
8745            if (!more) {
8746                Binder.restoreCallingIdentity(origId);
8747                return;
8748            }
8749        }
8750
8751        // No piece of data specified, dump everything.
8752        synchronized (this) {
8753            boolean needSep;
8754            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8755            if (needSep) {
8756                pw.println(" ");
8757            }
8758            if (dumpAll) {
8759                pw.println("-------------------------------------------------------------------------------");
8760            }
8761            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8762            if (needSep) {
8763                pw.println(" ");
8764            }
8765            if (dumpAll) {
8766                pw.println("-------------------------------------------------------------------------------");
8767            }
8768            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8769            if (needSep) {
8770                pw.println(" ");
8771            }
8772            if (dumpAll) {
8773                pw.println("-------------------------------------------------------------------------------");
8774            }
8775            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8776            if (needSep) {
8777                pw.println(" ");
8778            }
8779            if (dumpAll) {
8780                pw.println("-------------------------------------------------------------------------------");
8781            }
8782            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8783            if (needSep) {
8784                pw.println(" ");
8785            }
8786            if (dumpAll) {
8787                pw.println("-------------------------------------------------------------------------------");
8788            }
8789            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8790        }
8791        Binder.restoreCallingIdentity(origId);
8792    }
8793
8794    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8795            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8796        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8797        pw.println("  Main stack:");
8798        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8799                dumpPackage);
8800        pw.println(" ");
8801        pw.println("  Running activities (most recent first):");
8802        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8803                dumpPackage);
8804        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8805            pw.println(" ");
8806            pw.println("  Activities waiting for another to become visible:");
8807            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8808                    !dumpAll, false, dumpPackage);
8809        }
8810        if (mMainStack.mStoppingActivities.size() > 0) {
8811            pw.println(" ");
8812            pw.println("  Activities waiting to stop:");
8813            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8814                    !dumpAll, false, dumpPackage);
8815        }
8816        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8817            pw.println(" ");
8818            pw.println("  Activities waiting to sleep:");
8819            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8820                    !dumpAll, false, dumpPackage);
8821        }
8822        if (mMainStack.mFinishingActivities.size() > 0) {
8823            pw.println(" ");
8824            pw.println("  Activities waiting to finish:");
8825            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8826                    !dumpAll, false, dumpPackage);
8827        }
8828
8829        pw.println(" ");
8830        if (mMainStack.mPausingActivity != null) {
8831            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8832        }
8833        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8834        pw.println("  mFocusedActivity: " + mFocusedActivity);
8835        if (dumpAll) {
8836            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8837            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8838            pw.println("  mDismissKeyguardOnNextActivity: "
8839                    + mMainStack.mDismissKeyguardOnNextActivity);
8840        }
8841
8842        if (mRecentTasks.size() > 0) {
8843            pw.println();
8844            pw.println("  Recent tasks:");
8845
8846            final int N = mRecentTasks.size();
8847            for (int i=0; i<N; i++) {
8848                TaskRecord tr = mRecentTasks.get(i);
8849                if (dumpPackage != null) {
8850                    if (tr.realActivity == null ||
8851                            !dumpPackage.equals(tr.realActivity)) {
8852                        continue;
8853                    }
8854                }
8855                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8856                        pw.println(tr);
8857                if (dumpAll) {
8858                    mRecentTasks.get(i).dump(pw, "    ");
8859                }
8860            }
8861        }
8862
8863        if (dumpAll) {
8864            pw.println(" ");
8865            pw.println("  mCurTask: " + mCurTask);
8866        }
8867
8868        return true;
8869    }
8870
8871    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8872            int opti, boolean dumpAll, String dumpPackage) {
8873        boolean needSep = false;
8874        int numPers = 0;
8875
8876        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8877
8878        if (dumpAll) {
8879            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8880                final int NA = procs.size();
8881                for (int ia=0; ia<NA; ia++) {
8882                    ProcessRecord r = procs.valueAt(ia);
8883                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8884                        continue;
8885                    }
8886                    if (!needSep) {
8887                        pw.println("  All known processes:");
8888                        needSep = true;
8889                    }
8890                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8891                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8892                        pw.print(" "); pw.println(r);
8893                    r.dump(pw, "    ");
8894                    if (r.persistent) {
8895                        numPers++;
8896                    }
8897                }
8898            }
8899        }
8900
8901        if (mIsolatedProcesses.size() > 0) {
8902            if (needSep) pw.println(" ");
8903            needSep = true;
8904            pw.println("  Isolated process list (sorted by uid):");
8905            for (int i=0; i<mIsolatedProcesses.size(); i++) {
8906                ProcessRecord r = mIsolatedProcesses.valueAt(i);
8907                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8908                    continue;
8909                }
8910                pw.println(String.format("%sIsolated #%2d: %s",
8911                        "    ", i, r.toString()));
8912            }
8913        }
8914
8915        if (mLruProcesses.size() > 0) {
8916            if (needSep) pw.println(" ");
8917            needSep = true;
8918            pw.println("  Process LRU list (sorted by oom_adj):");
8919            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8920                    "Proc", "PERS", false, dumpPackage);
8921            needSep = true;
8922        }
8923
8924        if (dumpAll) {
8925            synchronized (mPidsSelfLocked) {
8926                boolean printed = false;
8927                for (int i=0; i<mPidsSelfLocked.size(); i++) {
8928                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
8929                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8930                        continue;
8931                    }
8932                    if (!printed) {
8933                        if (needSep) pw.println(" ");
8934                        needSep = true;
8935                        pw.println("  PID mappings:");
8936                        printed = true;
8937                    }
8938                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8939                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8940                }
8941            }
8942        }
8943
8944        if (mForegroundProcesses.size() > 0) {
8945            synchronized (mPidsSelfLocked) {
8946                boolean printed = false;
8947                for (int i=0; i<mForegroundProcesses.size(); i++) {
8948                    ProcessRecord r = mPidsSelfLocked.get(
8949                            mForegroundProcesses.valueAt(i).pid);
8950                    if (dumpPackage != null && (r == null
8951                            || !dumpPackage.equals(r.info.packageName))) {
8952                        continue;
8953                    }
8954                    if (!printed) {
8955                        if (needSep) pw.println(" ");
8956                        needSep = true;
8957                        pw.println("  Foreground Processes:");
8958                        printed = true;
8959                    }
8960                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
8961                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8962                }
8963            }
8964        }
8965
8966        if (mPersistentStartingProcesses.size() > 0) {
8967            if (needSep) pw.println(" ");
8968            needSep = true;
8969            pw.println("  Persisent processes that are starting:");
8970            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
8971                    "Starting Norm", "Restarting PERS", dumpPackage);
8972        }
8973
8974        if (mRemovedProcesses.size() > 0) {
8975            if (needSep) pw.println(" ");
8976            needSep = true;
8977            pw.println("  Processes that are being removed:");
8978            dumpProcessList(pw, this, mRemovedProcesses, "    ",
8979                    "Removed Norm", "Removed PERS", dumpPackage);
8980        }
8981
8982        if (mProcessesOnHold.size() > 0) {
8983            if (needSep) pw.println(" ");
8984            needSep = true;
8985            pw.println("  Processes that are on old until the system is ready:");
8986            dumpProcessList(pw, this, mProcessesOnHold, "    ",
8987                    "OnHold Norm", "OnHold PERS", dumpPackage);
8988        }
8989
8990        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
8991
8992        if (mProcessCrashTimes.getMap().size() > 0) {
8993            boolean printed = false;
8994            long now = SystemClock.uptimeMillis();
8995            for (Map.Entry<String, SparseArray<Long>> procs
8996                    : mProcessCrashTimes.getMap().entrySet()) {
8997                String pname = procs.getKey();
8998                SparseArray<Long> uids = procs.getValue();
8999                final int N = uids.size();
9000                for (int i=0; i<N; i++) {
9001                    int puid = uids.keyAt(i);
9002                    ProcessRecord r = mProcessNames.get(pname, puid);
9003                    if (dumpPackage != null && (r == null
9004                            || !dumpPackage.equals(r.info.packageName))) {
9005                        continue;
9006                    }
9007                    if (!printed) {
9008                        if (needSep) pw.println(" ");
9009                        needSep = true;
9010                        pw.println("  Time since processes crashed:");
9011                        printed = true;
9012                    }
9013                    pw.print("    Process "); pw.print(pname);
9014                            pw.print(" uid "); pw.print(puid);
9015                            pw.print(": last crashed ");
9016                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9017                            pw.println(" ago");
9018                }
9019            }
9020        }
9021
9022        if (mBadProcesses.getMap().size() > 0) {
9023            boolean printed = false;
9024            for (Map.Entry<String, SparseArray<Long>> procs
9025                    : mBadProcesses.getMap().entrySet()) {
9026                String pname = procs.getKey();
9027                SparseArray<Long> uids = procs.getValue();
9028                final int N = uids.size();
9029                for (int i=0; i<N; i++) {
9030                    int puid = uids.keyAt(i);
9031                    ProcessRecord r = mProcessNames.get(pname, puid);
9032                    if (dumpPackage != null && (r == null
9033                            || !dumpPackage.equals(r.info.packageName))) {
9034                        continue;
9035                    }
9036                    if (!printed) {
9037                        if (needSep) pw.println(" ");
9038                        needSep = true;
9039                        pw.println("  Bad processes:");
9040                    }
9041                    pw.print("    Bad process "); pw.print(pname);
9042                            pw.print(" uid "); pw.print(puid);
9043                            pw.print(": crashed at time ");
9044                            pw.println(uids.valueAt(i));
9045                }
9046            }
9047        }
9048
9049        pw.println();
9050        pw.println("  mHomeProcess: " + mHomeProcess);
9051        pw.println("  mPreviousProcess: " + mPreviousProcess);
9052        if (dumpAll) {
9053            StringBuilder sb = new StringBuilder(128);
9054            sb.append("  mPreviousProcessVisibleTime: ");
9055            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9056            pw.println(sb);
9057        }
9058        if (mHeavyWeightProcess != null) {
9059            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9060        }
9061        pw.println("  mConfiguration: " + mConfiguration);
9062        if (dumpAll) {
9063            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9064            if (mCompatModePackages.getPackages().size() > 0) {
9065                boolean printed = false;
9066                for (Map.Entry<String, Integer> entry
9067                        : mCompatModePackages.getPackages().entrySet()) {
9068                    String pkg = entry.getKey();
9069                    int mode = entry.getValue();
9070                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9071                        continue;
9072                    }
9073                    if (!printed) {
9074                        pw.println("  mScreenCompatPackages:");
9075                        printed = true;
9076                    }
9077                    pw.print("    "); pw.print(pkg); pw.print(": ");
9078                            pw.print(mode); pw.println();
9079                }
9080            }
9081        }
9082        if (mSleeping || mWentToSleep || mLockScreenShown) {
9083            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9084                    + " mLockScreenShown " + mLockScreenShown);
9085        }
9086        if (mShuttingDown) {
9087            pw.println("  mShuttingDown=" + mShuttingDown);
9088        }
9089        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9090                || mOrigWaitForDebugger) {
9091            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9092                    + " mDebugTransient=" + mDebugTransient
9093                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9094        }
9095        if (mOpenGlTraceApp != null) {
9096            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9097        }
9098        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9099                || mProfileFd != null) {
9100            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9101            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9102            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9103                    + mAutoStopProfiler);
9104        }
9105        if (mAlwaysFinishActivities || mController != null) {
9106            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9107                    + " mController=" + mController);
9108        }
9109        if (dumpAll) {
9110            pw.println("  Total persistent processes: " + numPers);
9111            pw.println("  mStartRunning=" + mStartRunning
9112                    + " mProcessesReady=" + mProcessesReady
9113                    + " mSystemReady=" + mSystemReady);
9114            pw.println("  mBooting=" + mBooting
9115                    + " mBooted=" + mBooted
9116                    + " mFactoryTest=" + mFactoryTest);
9117            pw.print("  mLastPowerCheckRealtime=");
9118                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9119                    pw.println("");
9120            pw.print("  mLastPowerCheckUptime=");
9121                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9122                    pw.println("");
9123            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9124            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9125            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9126            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9127                    + " mNumHiddenProcs=" + mNumHiddenProcs
9128                    + " mNumServiceProcs=" + mNumServiceProcs
9129                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9130        }
9131
9132        return true;
9133    }
9134
9135    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9136            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9137        if (mProcessesToGc.size() > 0) {
9138            boolean printed = false;
9139            long now = SystemClock.uptimeMillis();
9140            for (int i=0; i<mProcessesToGc.size(); i++) {
9141                ProcessRecord proc = mProcessesToGc.get(i);
9142                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9143                    continue;
9144                }
9145                if (!printed) {
9146                    if (needSep) pw.println(" ");
9147                    needSep = true;
9148                    pw.println("  Processes that are waiting to GC:");
9149                    printed = true;
9150                }
9151                pw.print("    Process "); pw.println(proc);
9152                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9153                        pw.print(", last gced=");
9154                        pw.print(now-proc.lastRequestedGc);
9155                        pw.print(" ms ago, last lowMem=");
9156                        pw.print(now-proc.lastLowMemory);
9157                        pw.println(" ms ago");
9158
9159            }
9160        }
9161        return needSep;
9162    }
9163
9164    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9165            int opti, boolean dumpAll) {
9166        boolean needSep = false;
9167
9168        if (mLruProcesses.size() > 0) {
9169            if (needSep) pw.println(" ");
9170            needSep = true;
9171            pw.println("  OOM levels:");
9172            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9173            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9174            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9175            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9176            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9177            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9178            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9179            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9180            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9181            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9182            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9183            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9184            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9185
9186            if (needSep) pw.println(" ");
9187            needSep = true;
9188            pw.println("  Process OOM control:");
9189            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9190                    "Proc", "PERS", true, null);
9191            needSep = true;
9192        }
9193
9194        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9195
9196        pw.println();
9197        pw.println("  mHomeProcess: " + mHomeProcess);
9198        pw.println("  mPreviousProcess: " + mPreviousProcess);
9199        if (mHeavyWeightProcess != null) {
9200            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9201        }
9202
9203        return true;
9204    }
9205
9206    /**
9207     * There are three ways to call this:
9208     *  - no provider specified: dump all the providers
9209     *  - a flattened component name that matched an existing provider was specified as the
9210     *    first arg: dump that one provider
9211     *  - the first arg isn't the flattened component name of an existing provider:
9212     *    dump all providers whose component contains the first arg as a substring
9213     */
9214    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9215            int opti, boolean dumpAll) {
9216        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9217    }
9218
9219    static class ItemMatcher {
9220        ArrayList<ComponentName> components;
9221        ArrayList<String> strings;
9222        ArrayList<Integer> objects;
9223        boolean all;
9224
9225        ItemMatcher() {
9226            all = true;
9227        }
9228
9229        void build(String name) {
9230            ComponentName componentName = ComponentName.unflattenFromString(name);
9231            if (componentName != null) {
9232                if (components == null) {
9233                    components = new ArrayList<ComponentName>();
9234                }
9235                components.add(componentName);
9236                all = false;
9237            } else {
9238                int objectId = 0;
9239                // Not a '/' separated full component name; maybe an object ID?
9240                try {
9241                    objectId = Integer.parseInt(name, 16);
9242                    if (objects == null) {
9243                        objects = new ArrayList<Integer>();
9244                    }
9245                    objects.add(objectId);
9246                    all = false;
9247                } catch (RuntimeException e) {
9248                    // Not an integer; just do string match.
9249                    if (strings == null) {
9250                        strings = new ArrayList<String>();
9251                    }
9252                    strings.add(name);
9253                    all = false;
9254                }
9255            }
9256        }
9257
9258        int build(String[] args, int opti) {
9259            for (; opti<args.length; opti++) {
9260                String name = args[opti];
9261                if ("--".equals(name)) {
9262                    return opti+1;
9263                }
9264                build(name);
9265            }
9266            return opti;
9267        }
9268
9269        boolean match(Object object, ComponentName comp) {
9270            if (all) {
9271                return true;
9272            }
9273            if (components != null) {
9274                for (int i=0; i<components.size(); i++) {
9275                    if (components.get(i).equals(comp)) {
9276                        return true;
9277                    }
9278                }
9279            }
9280            if (objects != null) {
9281                for (int i=0; i<objects.size(); i++) {
9282                    if (System.identityHashCode(object) == objects.get(i)) {
9283                        return true;
9284                    }
9285                }
9286            }
9287            if (strings != null) {
9288                String flat = comp.flattenToString();
9289                for (int i=0; i<strings.size(); i++) {
9290                    if (flat.contains(strings.get(i))) {
9291                        return true;
9292                    }
9293                }
9294            }
9295            return false;
9296        }
9297    }
9298
9299    /**
9300     * There are three things that cmd can be:
9301     *  - a flattened component name that matches an existing activity
9302     *  - the cmd arg isn't the flattened component name of an existing activity:
9303     *    dump all activity whose component contains the cmd as a substring
9304     *  - A hex number of the ActivityRecord object instance.
9305     */
9306    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9307            int opti, boolean dumpAll) {
9308        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9309
9310        if ("all".equals(name)) {
9311            synchronized (this) {
9312                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9313                    activities.add(r1);
9314                }
9315            }
9316        } else if ("top".equals(name)) {
9317            synchronized (this) {
9318                final int N = mMainStack.mHistory.size();
9319                if (N > 0) {
9320                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9321                }
9322            }
9323        } else {
9324            ItemMatcher matcher = new ItemMatcher();
9325            matcher.build(name);
9326
9327            synchronized (this) {
9328                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9329                    if (matcher.match(r1, r1.intent.getComponent())) {
9330                        activities.add(r1);
9331                    }
9332                }
9333            }
9334        }
9335
9336        if (activities.size() <= 0) {
9337            return false;
9338        }
9339
9340        String[] newArgs = new String[args.length - opti];
9341        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9342
9343        TaskRecord lastTask = null;
9344        boolean needSep = false;
9345        for (int i=activities.size()-1; i>=0; i--) {
9346            ActivityRecord r = (ActivityRecord)activities.get(i);
9347            if (needSep) {
9348                pw.println();
9349            }
9350            needSep = true;
9351            synchronized (this) {
9352                if (lastTask != r.task) {
9353                    lastTask = r.task;
9354                    pw.print("TASK "); pw.print(lastTask.affinity);
9355                            pw.print(" id="); pw.println(lastTask.taskId);
9356                    if (dumpAll) {
9357                        lastTask.dump(pw, "  ");
9358                    }
9359                }
9360            }
9361            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9362        }
9363        return true;
9364    }
9365
9366    /**
9367     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9368     * there is a thread associated with the activity.
9369     */
9370    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9371            final ActivityRecord r, String[] args, boolean dumpAll) {
9372        String innerPrefix = prefix + "  ";
9373        synchronized (this) {
9374            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9375                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9376                    pw.print(" pid=");
9377                    if (r.app != null) pw.println(r.app.pid);
9378                    else pw.println("(not running)");
9379            if (dumpAll) {
9380                r.dump(pw, innerPrefix);
9381            }
9382        }
9383        if (r.app != null && r.app.thread != null) {
9384            // flush anything that is already in the PrintWriter since the thread is going
9385            // to write to the file descriptor directly
9386            pw.flush();
9387            try {
9388                TransferPipe tp = new TransferPipe();
9389                try {
9390                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9391                            r.appToken, innerPrefix, args);
9392                    tp.go(fd);
9393                } finally {
9394                    tp.kill();
9395                }
9396            } catch (IOException e) {
9397                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9398            } catch (RemoteException e) {
9399                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9400            }
9401        }
9402    }
9403
9404    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9405            int opti, boolean dumpAll, String dumpPackage) {
9406        boolean needSep = false;
9407
9408        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9409        if (dumpAll) {
9410            if (mRegisteredReceivers.size() > 0) {
9411                boolean printed = false;
9412                Iterator it = mRegisteredReceivers.values().iterator();
9413                while (it.hasNext()) {
9414                    ReceiverList r = (ReceiverList)it.next();
9415                    if (dumpPackage != null && (r.app == null ||
9416                            !dumpPackage.equals(r.app.info.packageName))) {
9417                        continue;
9418                    }
9419                    if (!printed) {
9420                        pw.println("  Registered Receivers:");
9421                        needSep = true;
9422                        printed = true;
9423                    }
9424                    pw.print("  * "); pw.println(r);
9425                    r.dump(pw, "    ");
9426                }
9427            }
9428
9429            if (mReceiverResolver.dump(pw, needSep ?
9430                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9431                    "    ", dumpPackage, false)) {
9432                needSep = true;
9433            }
9434        }
9435
9436        for (BroadcastQueue q : mBroadcastQueues) {
9437            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9438        }
9439
9440        needSep = true;
9441
9442        if (mStickyBroadcasts != null && dumpPackage == null) {
9443            if (needSep) {
9444                pw.println();
9445            }
9446            needSep = true;
9447            pw.println("  Sticky broadcasts:");
9448            StringBuilder sb = new StringBuilder(128);
9449            for (Map.Entry<String, ArrayList<Intent>> ent
9450                    : mStickyBroadcasts.entrySet()) {
9451                pw.print("  * Sticky action "); pw.print(ent.getKey());
9452                if (dumpAll) {
9453                    pw.println(":");
9454                    ArrayList<Intent> intents = ent.getValue();
9455                    final int N = intents.size();
9456                    for (int i=0; i<N; i++) {
9457                        sb.setLength(0);
9458                        sb.append("    Intent: ");
9459                        intents.get(i).toShortString(sb, false, true, false, false);
9460                        pw.println(sb.toString());
9461                        Bundle bundle = intents.get(i).getExtras();
9462                        if (bundle != null) {
9463                            pw.print("      ");
9464                            pw.println(bundle.toString());
9465                        }
9466                    }
9467                } else {
9468                    pw.println("");
9469                }
9470            }
9471            needSep = true;
9472        }
9473
9474        if (dumpAll) {
9475            pw.println();
9476            for (BroadcastQueue queue : mBroadcastQueues) {
9477                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9478                        + queue.mBroadcastsScheduled);
9479            }
9480            pw.println("  mHandler:");
9481            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9482            needSep = true;
9483        }
9484
9485        return needSep;
9486    }
9487
9488    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9489            int opti, boolean dumpAll, String dumpPackage) {
9490        boolean needSep = true;
9491
9492        ItemMatcher matcher = new ItemMatcher();
9493        matcher.build(args, opti);
9494
9495        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9496
9497        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9498
9499        if (mLaunchingProviders.size() > 0) {
9500            boolean printed = false;
9501            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9502                ContentProviderRecord r = mLaunchingProviders.get(i);
9503                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9504                    continue;
9505                }
9506                if (!printed) {
9507                    if (needSep) pw.println(" ");
9508                    needSep = true;
9509                    pw.println("  Launching content providers:");
9510                    printed = true;
9511                }
9512                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9513                        pw.println(r);
9514            }
9515        }
9516
9517        if (mGrantedUriPermissions.size() > 0) {
9518            if (needSep) pw.println();
9519            needSep = true;
9520            pw.println("Granted Uri Permissions:");
9521            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9522                int uid = mGrantedUriPermissions.keyAt(i);
9523                HashMap<Uri, UriPermission> perms
9524                        = mGrantedUriPermissions.valueAt(i);
9525                pw.print("  * UID "); pw.print(uid);
9526                        pw.println(" holds:");
9527                for (UriPermission perm : perms.values()) {
9528                    pw.print("    "); pw.println(perm);
9529                    if (dumpAll) {
9530                        perm.dump(pw, "      ");
9531                    }
9532                }
9533            }
9534            needSep = true;
9535        }
9536
9537        return needSep;
9538    }
9539
9540    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9541            int opti, boolean dumpAll, String dumpPackage) {
9542        boolean needSep = false;
9543
9544        if (mIntentSenderRecords.size() > 0) {
9545            boolean printed = false;
9546            Iterator<WeakReference<PendingIntentRecord>> it
9547                    = mIntentSenderRecords.values().iterator();
9548            while (it.hasNext()) {
9549                WeakReference<PendingIntentRecord> ref = it.next();
9550                PendingIntentRecord rec = ref != null ? ref.get(): null;
9551                if (dumpPackage != null && (rec == null
9552                        || !dumpPackage.equals(rec.key.packageName))) {
9553                    continue;
9554                }
9555                if (!printed) {
9556                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9557                    printed = true;
9558                }
9559                needSep = true;
9560                if (rec != null) {
9561                    pw.print("  * "); pw.println(rec);
9562                    if (dumpAll) {
9563                        rec.dump(pw, "    ");
9564                    }
9565                } else {
9566                    pw.print("  * "); pw.println(ref);
9567                }
9568            }
9569        }
9570
9571        return needSep;
9572    }
9573
9574    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9575            String prefix, String label, boolean complete, boolean brief, boolean client,
9576            String dumpPackage) {
9577        TaskRecord lastTask = null;
9578        boolean needNL = false;
9579        final String innerPrefix = prefix + "      ";
9580        final String[] args = new String[0];
9581        for (int i=list.size()-1; i>=0; i--) {
9582            final ActivityRecord r = (ActivityRecord)list.get(i);
9583            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9584                continue;
9585            }
9586            final boolean full = !brief && (complete || !r.isInHistory());
9587            if (needNL) {
9588                pw.println(" ");
9589                needNL = false;
9590            }
9591            if (lastTask != r.task) {
9592                lastTask = r.task;
9593                pw.print(prefix);
9594                pw.print(full ? "* " : "  ");
9595                pw.println(lastTask);
9596                if (full) {
9597                    lastTask.dump(pw, prefix + "  ");
9598                } else if (complete) {
9599                    // Complete + brief == give a summary.  Isn't that obvious?!?
9600                    if (lastTask.intent != null) {
9601                        pw.print(prefix); pw.print("  ");
9602                                pw.println(lastTask.intent.toInsecureStringWithClip());
9603                    }
9604                }
9605            }
9606            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9607            pw.print(" #"); pw.print(i); pw.print(": ");
9608            pw.println(r);
9609            if (full) {
9610                r.dump(pw, innerPrefix);
9611            } else if (complete) {
9612                // Complete + brief == give a summary.  Isn't that obvious?!?
9613                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9614                if (r.app != null) {
9615                    pw.print(innerPrefix); pw.println(r.app);
9616                }
9617            }
9618            if (client && r.app != null && r.app.thread != null) {
9619                // flush anything that is already in the PrintWriter since the thread is going
9620                // to write to the file descriptor directly
9621                pw.flush();
9622                try {
9623                    TransferPipe tp = new TransferPipe();
9624                    try {
9625                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9626                                r.appToken, innerPrefix, args);
9627                        // Short timeout, since blocking here can
9628                        // deadlock with the application.
9629                        tp.go(fd, 2000);
9630                    } finally {
9631                        tp.kill();
9632                    }
9633                } catch (IOException e) {
9634                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9635                } catch (RemoteException e) {
9636                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9637                }
9638                needNL = true;
9639            }
9640        }
9641    }
9642
9643    private static String buildOomTag(String prefix, String space, int val, int base) {
9644        if (val == base) {
9645            if (space == null) return prefix;
9646            return prefix + "  ";
9647        }
9648        return prefix + "+" + Integer.toString(val-base);
9649    }
9650
9651    private static final int dumpProcessList(PrintWriter pw,
9652            ActivityManagerService service, List list,
9653            String prefix, String normalLabel, String persistentLabel,
9654            String dumpPackage) {
9655        int numPers = 0;
9656        final int N = list.size()-1;
9657        for (int i=N; i>=0; i--) {
9658            ProcessRecord r = (ProcessRecord)list.get(i);
9659            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9660                continue;
9661            }
9662            pw.println(String.format("%s%s #%2d: %s",
9663                    prefix, (r.persistent ? persistentLabel : normalLabel),
9664                    i, r.toString()));
9665            if (r.persistent) {
9666                numPers++;
9667            }
9668        }
9669        return numPers;
9670    }
9671
9672    private static final boolean dumpProcessOomList(PrintWriter pw,
9673            ActivityManagerService service, List<ProcessRecord> origList,
9674            String prefix, String normalLabel, String persistentLabel,
9675            boolean inclDetails, String dumpPackage) {
9676
9677        ArrayList<Pair<ProcessRecord, Integer>> list
9678                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9679        for (int i=0; i<origList.size(); i++) {
9680            ProcessRecord r = origList.get(i);
9681            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9682                continue;
9683            }
9684            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9685        }
9686
9687        if (list.size() <= 0) {
9688            return false;
9689        }
9690
9691        Comparator<Pair<ProcessRecord, Integer>> comparator
9692                = new Comparator<Pair<ProcessRecord, Integer>>() {
9693            @Override
9694            public int compare(Pair<ProcessRecord, Integer> object1,
9695                    Pair<ProcessRecord, Integer> object2) {
9696                if (object1.first.setAdj != object2.first.setAdj) {
9697                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9698                }
9699                if (object1.second.intValue() != object2.second.intValue()) {
9700                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9701                }
9702                return 0;
9703            }
9704        };
9705
9706        Collections.sort(list, comparator);
9707
9708        final long curRealtime = SystemClock.elapsedRealtime();
9709        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9710        final long curUptime = SystemClock.uptimeMillis();
9711        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9712
9713        for (int i=list.size()-1; i>=0; i--) {
9714            ProcessRecord r = list.get(i).first;
9715            String oomAdj;
9716            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9717                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9718            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9719                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9720            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9721                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9722            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9723                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9724            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9725                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9726            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9727                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9728            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9729                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9730            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9731                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9732            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9733                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9734            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9735                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9736            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9737                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9738            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9739                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9740            } else {
9741                oomAdj = Integer.toString(r.setAdj);
9742            }
9743            String schedGroup;
9744            switch (r.setSchedGroup) {
9745                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9746                    schedGroup = "B";
9747                    break;
9748                case Process.THREAD_GROUP_DEFAULT:
9749                    schedGroup = "F";
9750                    break;
9751                default:
9752                    schedGroup = Integer.toString(r.setSchedGroup);
9753                    break;
9754            }
9755            String foreground;
9756            if (r.foregroundActivities) {
9757                foreground = "A";
9758            } else if (r.foregroundServices) {
9759                foreground = "S";
9760            } else {
9761                foreground = " ";
9762            }
9763            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9764                    prefix, (r.persistent ? persistentLabel : normalLabel),
9765                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9766                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9767            if (r.adjSource != null || r.adjTarget != null) {
9768                pw.print(prefix);
9769                pw.print("    ");
9770                if (r.adjTarget instanceof ComponentName) {
9771                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9772                } else if (r.adjTarget != null) {
9773                    pw.print(r.adjTarget.toString());
9774                } else {
9775                    pw.print("{null}");
9776                }
9777                pw.print("<=");
9778                if (r.adjSource instanceof ProcessRecord) {
9779                    pw.print("Proc{");
9780                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9781                    pw.println("}");
9782                } else if (r.adjSource != null) {
9783                    pw.println(r.adjSource.toString());
9784                } else {
9785                    pw.println("{null}");
9786                }
9787            }
9788            if (inclDetails) {
9789                pw.print(prefix);
9790                pw.print("    ");
9791                pw.print("oom: max="); pw.print(r.maxAdj);
9792                pw.print(" hidden="); pw.print(r.hiddenAdj);
9793                pw.print(" empty="); pw.print(r.emptyAdj);
9794                pw.print(" curRaw="); pw.print(r.curRawAdj);
9795                pw.print(" setRaw="); pw.print(r.setRawAdj);
9796                pw.print(" cur="); pw.print(r.curAdj);
9797                pw.print(" set="); pw.println(r.setAdj);
9798                pw.print(prefix);
9799                pw.print("    ");
9800                pw.print("keeping="); pw.print(r.keeping);
9801                pw.print(" hidden="); pw.print(r.hidden);
9802                pw.print(" empty="); pw.print(r.empty);
9803                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
9804
9805                if (!r.keeping) {
9806                    if (r.lastWakeTime != 0) {
9807                        long wtime;
9808                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9809                        synchronized (stats) {
9810                            wtime = stats.getProcessWakeTime(r.info.uid,
9811                                    r.pid, curRealtime);
9812                        }
9813                        long timeUsed = wtime - r.lastWakeTime;
9814                        pw.print(prefix);
9815                        pw.print("    ");
9816                        pw.print("keep awake over ");
9817                        TimeUtils.formatDuration(realtimeSince, pw);
9818                        pw.print(" used ");
9819                        TimeUtils.formatDuration(timeUsed, pw);
9820                        pw.print(" (");
9821                        pw.print((timeUsed*100)/realtimeSince);
9822                        pw.println("%)");
9823                    }
9824                    if (r.lastCpuTime != 0) {
9825                        long timeUsed = r.curCpuTime - r.lastCpuTime;
9826                        pw.print(prefix);
9827                        pw.print("    ");
9828                        pw.print("run cpu over ");
9829                        TimeUtils.formatDuration(uptimeSince, pw);
9830                        pw.print(" used ");
9831                        TimeUtils.formatDuration(timeUsed, pw);
9832                        pw.print(" (");
9833                        pw.print((timeUsed*100)/uptimeSince);
9834                        pw.println("%)");
9835                    }
9836                }
9837            }
9838        }
9839        return true;
9840    }
9841
9842    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
9843        ArrayList<ProcessRecord> procs;
9844        synchronized (this) {
9845            if (args != null && args.length > start
9846                    && args[start].charAt(0) != '-') {
9847                procs = new ArrayList<ProcessRecord>();
9848                int pid = -1;
9849                try {
9850                    pid = Integer.parseInt(args[start]);
9851                } catch (NumberFormatException e) {
9852
9853                }
9854                for (int i=mLruProcesses.size()-1; i>=0; i--) {
9855                    ProcessRecord proc = mLruProcesses.get(i);
9856                    if (proc.pid == pid) {
9857                        procs.add(proc);
9858                    } else if (proc.processName.equals(args[start])) {
9859                        procs.add(proc);
9860                    }
9861                }
9862                if (procs.size() <= 0) {
9863                    pw.println("No process found for: " + args[start]);
9864                    return null;
9865                }
9866            } else {
9867                procs = new ArrayList<ProcessRecord>(mLruProcesses);
9868            }
9869        }
9870        return procs;
9871    }
9872
9873    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9874            PrintWriter pw, String[] args) {
9875        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9876        if (procs == null) {
9877            return;
9878        }
9879
9880        long uptime = SystemClock.uptimeMillis();
9881        long realtime = SystemClock.elapsedRealtime();
9882        pw.println("Applications Graphics Acceleration Info:");
9883        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9884
9885        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9886            ProcessRecord r = procs.get(i);
9887            if (r.thread != null) {
9888                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9889                pw.flush();
9890                try {
9891                    TransferPipe tp = new TransferPipe();
9892                    try {
9893                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9894                        tp.go(fd);
9895                    } finally {
9896                        tp.kill();
9897                    }
9898                } catch (IOException e) {
9899                    pw.println("Failure while dumping the app: " + r);
9900                    pw.flush();
9901                } catch (RemoteException e) {
9902                    pw.println("Got a RemoteException while dumping the app " + r);
9903                    pw.flush();
9904                }
9905            }
9906        }
9907    }
9908
9909    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
9910        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9911        if (procs == null) {
9912            return;
9913        }
9914
9915        pw.println("Applications Database Info:");
9916
9917        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9918            ProcessRecord r = procs.get(i);
9919            if (r.thread != null) {
9920                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
9921                pw.flush();
9922                try {
9923                    TransferPipe tp = new TransferPipe();
9924                    try {
9925                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
9926                        tp.go(fd);
9927                    } finally {
9928                        tp.kill();
9929                    }
9930                } catch (IOException e) {
9931                    pw.println("Failure while dumping the app: " + r);
9932                    pw.flush();
9933                } catch (RemoteException e) {
9934                    pw.println("Got a RemoteException while dumping the app " + r);
9935                    pw.flush();
9936                }
9937            }
9938        }
9939    }
9940
9941    final static class MemItem {
9942        final String label;
9943        final String shortLabel;
9944        final long pss;
9945        final int id;
9946        ArrayList<MemItem> subitems;
9947
9948        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
9949            label = _label;
9950            shortLabel = _shortLabel;
9951            pss = _pss;
9952            id = _id;
9953        }
9954    }
9955
9956    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9957            boolean sort) {
9958        if (sort) {
9959            Collections.sort(items, new Comparator<MemItem>() {
9960                @Override
9961                public int compare(MemItem lhs, MemItem rhs) {
9962                    if (lhs.pss < rhs.pss) {
9963                        return 1;
9964                    } else if (lhs.pss > rhs.pss) {
9965                        return -1;
9966                    }
9967                    return 0;
9968                }
9969            });
9970        }
9971
9972        for (int i=0; i<items.size(); i++) {
9973            MemItem mi = items.get(i);
9974            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
9975            if (mi.subitems != null) {
9976                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
9977            }
9978        }
9979    }
9980
9981    // These are in KB.
9982    static final long[] DUMP_MEM_BUCKETS = new long[] {
9983        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
9984        120*1024, 160*1024, 200*1024,
9985        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
9986        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
9987    };
9988
9989    static final void appendMemBucket(StringBuilder out, long memKB, String label,
9990            boolean stackLike) {
9991        int start = label.lastIndexOf('.');
9992        if (start >= 0) start++;
9993        else start = 0;
9994        int end = label.length();
9995        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
9996            if (DUMP_MEM_BUCKETS[i] >= memKB) {
9997                long bucket = DUMP_MEM_BUCKETS[i]/1024;
9998                out.append(bucket);
9999                out.append(stackLike ? "MB." : "MB ");
10000                out.append(label, start, end);
10001                return;
10002            }
10003        }
10004        out.append(memKB/1024);
10005        out.append(stackLike ? "MB." : "MB ");
10006        out.append(label, start, end);
10007    }
10008
10009    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10010            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10011            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10012            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10013            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10014    };
10015    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10016            "System", "Persistent", "Foreground",
10017            "Visible", "Perceptible", "Heavy Weight",
10018            "Backup", "A Services", "Home", "Previous",
10019            "B Services", "Background"
10020    };
10021
10022    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10023            PrintWriter pw, String prefix, String[] args, boolean brief,
10024            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10025        boolean dumpAll = false;
10026        boolean oomOnly = false;
10027
10028        int opti = 0;
10029        while (opti < args.length) {
10030            String opt = args[opti];
10031            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10032                break;
10033            }
10034            opti++;
10035            if ("-a".equals(opt)) {
10036                dumpAll = true;
10037            } else if ("--oom".equals(opt)) {
10038                oomOnly = true;
10039            } else if ("-h".equals(opt)) {
10040                pw.println("meminfo dump options: [-a] [--oom] [process]");
10041                pw.println("  -a: include all available information for each process.");
10042                pw.println("  --oom: only show processes organized by oom adj.");
10043                pw.println("If [process] is specified it can be the name or ");
10044                pw.println("pid of a specific process to dump.");
10045                return;
10046            } else {
10047                pw.println("Unknown argument: " + opt + "; use -h for help");
10048            }
10049        }
10050
10051        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10052        if (procs == null) {
10053            return;
10054        }
10055
10056        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10057        long uptime = SystemClock.uptimeMillis();
10058        long realtime = SystemClock.elapsedRealtime();
10059
10060        if (procs.size() == 1 || isCheckinRequest) {
10061            dumpAll = true;
10062        }
10063
10064        if (isCheckinRequest) {
10065            // short checkin version
10066            pw.println(uptime + "," + realtime);
10067            pw.flush();
10068        } else {
10069            pw.println("Applications Memory Usage (kB):");
10070            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10071        }
10072
10073        String[] innerArgs = new String[args.length-opti];
10074        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10075
10076        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10077        long nativePss=0, dalvikPss=0, otherPss=0;
10078        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10079
10080        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10081        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10082                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10083
10084        long totalPss = 0;
10085
10086        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10087            ProcessRecord r = procs.get(i);
10088            if (r.thread != null) {
10089                if (!isCheckinRequest && dumpAll) {
10090                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10091                    pw.flush();
10092                }
10093                Debug.MemoryInfo mi = null;
10094                if (dumpAll) {
10095                    try {
10096                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10097                    } catch (RemoteException e) {
10098                        if (!isCheckinRequest) {
10099                            pw.println("Got RemoteException!");
10100                            pw.flush();
10101                        }
10102                    }
10103                } else {
10104                    mi = new Debug.MemoryInfo();
10105                    Debug.getMemoryInfo(r.pid, mi);
10106                }
10107
10108                if (!isCheckinRequest && mi != null) {
10109                    long myTotalPss = mi.getTotalPss();
10110                    totalPss += myTotalPss;
10111                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10112                            r.processName, myTotalPss, 0);
10113                    procMems.add(pssItem);
10114
10115                    nativePss += mi.nativePss;
10116                    dalvikPss += mi.dalvikPss;
10117                    otherPss += mi.otherPss;
10118                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10119                        long mem = mi.getOtherPss(j);
10120                        miscPss[j] += mem;
10121                        otherPss -= mem;
10122                    }
10123
10124                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10125                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10126                                || oomIndex == (oomPss.length-1)) {
10127                            oomPss[oomIndex] += myTotalPss;
10128                            if (oomProcs[oomIndex] == null) {
10129                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10130                            }
10131                            oomProcs[oomIndex].add(pssItem);
10132                            break;
10133                        }
10134                    }
10135                }
10136            }
10137        }
10138
10139        if (!isCheckinRequest && procs.size() > 1) {
10140            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10141
10142            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10143            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10144            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10145            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10146                String label = Debug.MemoryInfo.getOtherLabel(j);
10147                catMems.add(new MemItem(label, label, miscPss[j], j));
10148            }
10149
10150            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10151            for (int j=0; j<oomPss.length; j++) {
10152                if (oomPss[j] != 0) {
10153                    String label = DUMP_MEM_OOM_LABEL[j];
10154                    MemItem item = new MemItem(label, label, oomPss[j],
10155                            DUMP_MEM_OOM_ADJ[j]);
10156                    item.subitems = oomProcs[j];
10157                    oomMems.add(item);
10158                }
10159            }
10160
10161            if (outTag != null || outStack != null) {
10162                if (outTag != null) {
10163                    appendMemBucket(outTag, totalPss, "total", false);
10164                }
10165                if (outStack != null) {
10166                    appendMemBucket(outStack, totalPss, "total", true);
10167                }
10168                boolean firstLine = true;
10169                for (int i=0; i<oomMems.size(); i++) {
10170                    MemItem miCat = oomMems.get(i);
10171                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10172                        continue;
10173                    }
10174                    if (miCat.id < ProcessList.SERVICE_ADJ
10175                            || miCat.id == ProcessList.HOME_APP_ADJ
10176                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10177                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10178                            outTag.append(" / ");
10179                        }
10180                        if (outStack != null) {
10181                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10182                                if (firstLine) {
10183                                    outStack.append(":");
10184                                    firstLine = false;
10185                                }
10186                                outStack.append("\n\t at ");
10187                            } else {
10188                                outStack.append("$");
10189                            }
10190                        }
10191                        for (int j=0; j<miCat.subitems.size(); j++) {
10192                            MemItem mi = miCat.subitems.get(j);
10193                            if (j > 0) {
10194                                if (outTag != null) {
10195                                    outTag.append(" ");
10196                                }
10197                                if (outStack != null) {
10198                                    outStack.append("$");
10199                                }
10200                            }
10201                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10202                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10203                            }
10204                            if (outStack != null) {
10205                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10206                            }
10207                        }
10208                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10209                            outStack.append("(");
10210                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10211                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10212                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10213                                    outStack.append(":");
10214                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10215                                }
10216                            }
10217                            outStack.append(")");
10218                        }
10219                    }
10220                }
10221            }
10222
10223            if (!brief && !oomOnly) {
10224                pw.println();
10225                pw.println("Total PSS by process:");
10226                dumpMemItems(pw, "  ", procMems, true);
10227                pw.println();
10228            }
10229            pw.println("Total PSS by OOM adjustment:");
10230            dumpMemItems(pw, "  ", oomMems, false);
10231            if (!oomOnly) {
10232                PrintWriter out = categoryPw != null ? categoryPw : pw;
10233                out.println();
10234                out.println("Total PSS by category:");
10235                dumpMemItems(out, "  ", catMems, true);
10236            }
10237            pw.println();
10238            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10239            final int[] SINGLE_LONG_FORMAT = new int[] {
10240                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10241            };
10242            long[] longOut = new long[1];
10243            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10244                    SINGLE_LONG_FORMAT, null, longOut, null);
10245            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10246            longOut[0] = 0;
10247            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10248                    SINGLE_LONG_FORMAT, null, longOut, null);
10249            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10250            longOut[0] = 0;
10251            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10252                    SINGLE_LONG_FORMAT, null, longOut, null);
10253            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10254            longOut[0] = 0;
10255            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10256                    SINGLE_LONG_FORMAT, null, longOut, null);
10257            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10258            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10259                    pw.print(shared); pw.println(" kB");
10260            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10261                    pw.print(voltile); pw.println(" kB volatile");
10262        }
10263    }
10264
10265    /**
10266     * Searches array of arguments for the specified string
10267     * @param args array of argument strings
10268     * @param value value to search for
10269     * @return true if the value is contained in the array
10270     */
10271    private static boolean scanArgs(String[] args, String value) {
10272        if (args != null) {
10273            for (String arg : args) {
10274                if (value.equals(arg)) {
10275                    return true;
10276                }
10277            }
10278        }
10279        return false;
10280    }
10281
10282    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10283            ContentProviderRecord cpr, boolean always) {
10284        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10285
10286        if (!inLaunching || always) {
10287            synchronized (cpr) {
10288                cpr.launchingApp = null;
10289                cpr.notifyAll();
10290            }
10291            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10292            String names[] = cpr.info.authority.split(";");
10293            for (int j = 0; j < names.length; j++) {
10294                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10295            }
10296        }
10297
10298        for (int i=0; i<cpr.connections.size(); i++) {
10299            ContentProviderConnection conn = cpr.connections.get(i);
10300            if (conn.waiting) {
10301                // If this connection is waiting for the provider, then we don't
10302                // need to mess with its process unless we are always removing
10303                // or for some reason the provider is not currently launching.
10304                if (inLaunching && !always) {
10305                    continue;
10306                }
10307            }
10308            ProcessRecord capp = conn.client;
10309            conn.dead = true;
10310            if (conn.stableCount > 0) {
10311                if (!capp.persistent && capp.thread != null
10312                        && capp.pid != 0
10313                        && capp.pid != MY_PID) {
10314                    Slog.i(TAG, "Kill " + capp.processName
10315                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10316                            + " in dying process " + (proc != null ? proc.processName : "??"));
10317                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10318                            capp.processName, capp.setAdj, "dying provider "
10319                                    + cpr.name.toShortString());
10320                    Process.killProcessQuiet(capp.pid);
10321                }
10322            } else if (capp.thread != null && conn.provider.provider != null) {
10323                try {
10324                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10325                } catch (RemoteException e) {
10326                }
10327                // In the protocol here, we don't expect the client to correctly
10328                // clean up this connection, we'll just remove it.
10329                cpr.connections.remove(i);
10330                conn.client.conProviders.remove(conn);
10331            }
10332        }
10333
10334        if (inLaunching && always) {
10335            mLaunchingProviders.remove(cpr);
10336        }
10337        return inLaunching;
10338    }
10339
10340    /**
10341     * Main code for cleaning up a process when it has gone away.  This is
10342     * called both as a result of the process dying, or directly when stopping
10343     * a process when running in single process mode.
10344     */
10345    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10346            boolean restarting, boolean allowRestart, int index) {
10347        if (index >= 0) {
10348            mLruProcesses.remove(index);
10349        }
10350
10351        mProcessesToGc.remove(app);
10352
10353        // Dismiss any open dialogs.
10354        if (app.crashDialog != null) {
10355            app.crashDialog.dismiss();
10356            app.crashDialog = null;
10357        }
10358        if (app.anrDialog != null) {
10359            app.anrDialog.dismiss();
10360            app.anrDialog = null;
10361        }
10362        if (app.waitDialog != null) {
10363            app.waitDialog.dismiss();
10364            app.waitDialog = null;
10365        }
10366
10367        app.crashing = false;
10368        app.notResponding = false;
10369
10370        app.resetPackageList();
10371        app.unlinkDeathRecipient();
10372        app.thread = null;
10373        app.forcingToForeground = null;
10374        app.foregroundServices = false;
10375        app.foregroundActivities = false;
10376        app.hasShownUi = false;
10377        app.hasAboveClient = false;
10378
10379        mServices.killServicesLocked(app, allowRestart);
10380
10381        boolean restart = false;
10382
10383        // Remove published content providers.
10384        if (!app.pubProviders.isEmpty()) {
10385            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10386            while (it.hasNext()) {
10387                ContentProviderRecord cpr = it.next();
10388
10389                final boolean always = app.bad || !allowRestart;
10390                if (removeDyingProviderLocked(app, cpr, always) || always) {
10391                    // We left the provider in the launching list, need to
10392                    // restart it.
10393                    restart = true;
10394                }
10395
10396                cpr.provider = null;
10397                cpr.proc = null;
10398            }
10399            app.pubProviders.clear();
10400        }
10401
10402        // Take care of any launching providers waiting for this process.
10403        if (checkAppInLaunchingProvidersLocked(app, false)) {
10404            restart = true;
10405        }
10406
10407        // Unregister from connected content providers.
10408        if (!app.conProviders.isEmpty()) {
10409            for (int i=0; i<app.conProviders.size(); i++) {
10410                ContentProviderConnection conn = app.conProviders.get(i);
10411                conn.provider.connections.remove(conn);
10412            }
10413            app.conProviders.clear();
10414        }
10415
10416        // At this point there may be remaining entries in mLaunchingProviders
10417        // where we were the only one waiting, so they are no longer of use.
10418        // Look for these and clean up if found.
10419        // XXX Commented out for now.  Trying to figure out a way to reproduce
10420        // the actual situation to identify what is actually going on.
10421        if (false) {
10422            for (int i=0; i<mLaunchingProviders.size(); i++) {
10423                ContentProviderRecord cpr = (ContentProviderRecord)
10424                        mLaunchingProviders.get(i);
10425                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10426                    synchronized (cpr) {
10427                        cpr.launchingApp = null;
10428                        cpr.notifyAll();
10429                    }
10430                }
10431            }
10432        }
10433
10434        skipCurrentReceiverLocked(app);
10435
10436        // Unregister any receivers.
10437        if (app.receivers.size() > 0) {
10438            Iterator<ReceiverList> it = app.receivers.iterator();
10439            while (it.hasNext()) {
10440                removeReceiverLocked(it.next());
10441            }
10442            app.receivers.clear();
10443        }
10444
10445        // If the app is undergoing backup, tell the backup manager about it
10446        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10447            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10448            try {
10449                IBackupManager bm = IBackupManager.Stub.asInterface(
10450                        ServiceManager.getService(Context.BACKUP_SERVICE));
10451                bm.agentDisconnected(app.info.packageName);
10452            } catch (RemoteException e) {
10453                // can't happen; backup manager is local
10454            }
10455        }
10456
10457        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10458            ProcessChangeItem item = mPendingProcessChanges.get(i);
10459            if (item.pid == app.pid) {
10460                mPendingProcessChanges.remove(i);
10461                mAvailProcessChanges.add(item);
10462            }
10463        }
10464        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10465
10466        // If the caller is restarting this app, then leave it in its
10467        // current lists and let the caller take care of it.
10468        if (restarting) {
10469            return;
10470        }
10471
10472        if (!app.persistent || app.isolated) {
10473            if (DEBUG_PROCESSES) Slog.v(TAG,
10474                    "Removing non-persistent process during cleanup: " + app);
10475            mProcessNames.remove(app.processName, app.uid);
10476            mIsolatedProcesses.remove(app.uid);
10477            if (mHeavyWeightProcess == app) {
10478                mHeavyWeightProcess = null;
10479                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10480            }
10481        } else if (!app.removed) {
10482            // This app is persistent, so we need to keep its record around.
10483            // If it is not already on the pending app list, add it there
10484            // and start a new process for it.
10485            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10486                mPersistentStartingProcesses.add(app);
10487                restart = true;
10488            }
10489        }
10490        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10491                "Clean-up removing on hold: " + app);
10492        mProcessesOnHold.remove(app);
10493
10494        if (app == mHomeProcess) {
10495            mHomeProcess = null;
10496        }
10497        if (app == mPreviousProcess) {
10498            mPreviousProcess = null;
10499        }
10500
10501        if (restart && !app.isolated) {
10502            // We have components that still need to be running in the
10503            // process, so re-launch it.
10504            mProcessNames.put(app.processName, app.uid, app);
10505            startProcessLocked(app, "restart", app.processName);
10506        } else if (app.pid > 0 && app.pid != MY_PID) {
10507            // Goodbye!
10508            synchronized (mPidsSelfLocked) {
10509                mPidsSelfLocked.remove(app.pid);
10510                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10511            }
10512            app.setPid(0);
10513        }
10514    }
10515
10516    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10517        // Look through the content providers we are waiting to have launched,
10518        // and if any run in this process then either schedule a restart of
10519        // the process or kill the client waiting for it if this process has
10520        // gone bad.
10521        int NL = mLaunchingProviders.size();
10522        boolean restart = false;
10523        for (int i=0; i<NL; i++) {
10524            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10525            if (cpr.launchingApp == app) {
10526                if (!alwaysBad && !app.bad) {
10527                    restart = true;
10528                } else {
10529                    removeDyingProviderLocked(app, cpr, true);
10530                    NL = mLaunchingProviders.size();
10531                }
10532            }
10533        }
10534        return restart;
10535    }
10536
10537    // =========================================================
10538    // SERVICES
10539    // =========================================================
10540
10541    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10542            int flags) {
10543        enforceNotIsolatedCaller("getServices");
10544        synchronized (this) {
10545            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10546        }
10547    }
10548
10549    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10550        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10551        synchronized (this) {
10552            return mServices.getRunningServiceControlPanelLocked(name);
10553        }
10554    }
10555
10556    public ComponentName startService(IApplicationThread caller, Intent service,
10557            String resolvedType, int userId) {
10558        enforceNotIsolatedCaller("startService");
10559        // Refuse possible leaked file descriptors
10560        if (service != null && service.hasFileDescriptors() == true) {
10561            throw new IllegalArgumentException("File descriptors passed in Intent");
10562        }
10563
10564        if (DEBUG_SERVICE)
10565            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10566        synchronized(this) {
10567            final int callingPid = Binder.getCallingPid();
10568            final int callingUid = Binder.getCallingUid();
10569            checkValidCaller(callingUid, userId);
10570            final long origId = Binder.clearCallingIdentity();
10571            ComponentName res = mServices.startServiceLocked(caller, service,
10572                    resolvedType, callingPid, callingUid, userId);
10573            Binder.restoreCallingIdentity(origId);
10574            return res;
10575        }
10576    }
10577
10578    ComponentName startServiceInPackage(int uid,
10579            Intent service, String resolvedType) {
10580        synchronized(this) {
10581            if (DEBUG_SERVICE)
10582                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10583            final long origId = Binder.clearCallingIdentity();
10584            ComponentName res = mServices.startServiceLocked(null, service,
10585                    resolvedType, -1, uid, UserHandle.getUserId(uid));
10586            Binder.restoreCallingIdentity(origId);
10587            return res;
10588        }
10589    }
10590
10591    public int stopService(IApplicationThread caller, Intent service,
10592            String resolvedType, int userId) {
10593        enforceNotIsolatedCaller("stopService");
10594        // Refuse possible leaked file descriptors
10595        if (service != null && service.hasFileDescriptors() == true) {
10596            throw new IllegalArgumentException("File descriptors passed in Intent");
10597        }
10598
10599        checkValidCaller(Binder.getCallingUid(), userId);
10600
10601        synchronized(this) {
10602            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10603        }
10604    }
10605
10606    public IBinder peekService(Intent service, String resolvedType) {
10607        enforceNotIsolatedCaller("peekService");
10608        // Refuse possible leaked file descriptors
10609        if (service != null && service.hasFileDescriptors() == true) {
10610            throw new IllegalArgumentException("File descriptors passed in Intent");
10611        }
10612        synchronized(this) {
10613            return mServices.peekServiceLocked(service, resolvedType);
10614        }
10615    }
10616
10617    public boolean stopServiceToken(ComponentName className, IBinder token,
10618            int startId) {
10619        synchronized(this) {
10620            return mServices.stopServiceTokenLocked(className, token, startId);
10621        }
10622    }
10623
10624    public void setServiceForeground(ComponentName className, IBinder token,
10625            int id, Notification notification, boolean removeNotification) {
10626        synchronized(this) {
10627            mServices.setServiceForegroundLocked(className, token, id, notification,
10628                    removeNotification);
10629        }
10630    }
10631
10632    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10633            String className, int flags) {
10634        boolean result = false;
10635        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10636            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10637                if (ActivityManager.checkUidPermission(
10638                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10639                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10640                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10641                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10642                            + " requests FLAG_SINGLE_USER, but app does not hold "
10643                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10644                    Slog.w(TAG, msg);
10645                    throw new SecurityException(msg);
10646                }
10647                result = true;
10648            }
10649        } else if (componentProcessName == aInfo.packageName) {
10650            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10651        } else if ("system".equals(componentProcessName)) {
10652            result = true;
10653        }
10654        if (DEBUG_MU) {
10655            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10656                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10657        }
10658        return result;
10659    }
10660
10661    public int bindService(IApplicationThread caller, IBinder token,
10662            Intent service, String resolvedType,
10663            IServiceConnection connection, int flags, int userId) {
10664        enforceNotIsolatedCaller("bindService");
10665        // Refuse possible leaked file descriptors
10666        if (service != null && service.hasFileDescriptors() == true) {
10667            throw new IllegalArgumentException("File descriptors passed in Intent");
10668        }
10669
10670        checkValidCaller(Binder.getCallingUid(), userId);
10671
10672        synchronized(this) {
10673            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10674                    connection, flags, userId);
10675        }
10676    }
10677
10678    public boolean unbindService(IServiceConnection connection) {
10679        synchronized (this) {
10680            return mServices.unbindServiceLocked(connection);
10681        }
10682    }
10683
10684    public void publishService(IBinder token, Intent intent, IBinder service) {
10685        // Refuse possible leaked file descriptors
10686        if (intent != null && intent.hasFileDescriptors() == true) {
10687            throw new IllegalArgumentException("File descriptors passed in Intent");
10688        }
10689
10690        synchronized(this) {
10691            if (!(token instanceof ServiceRecord)) {
10692                throw new IllegalArgumentException("Invalid service token");
10693            }
10694            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
10695        }
10696    }
10697
10698    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10699        // Refuse possible leaked file descriptors
10700        if (intent != null && intent.hasFileDescriptors() == true) {
10701            throw new IllegalArgumentException("File descriptors passed in Intent");
10702        }
10703
10704        synchronized(this) {
10705            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
10706        }
10707    }
10708
10709    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10710        synchronized(this) {
10711            if (!(token instanceof ServiceRecord)) {
10712                throw new IllegalArgumentException("Invalid service token");
10713            }
10714            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
10715        }
10716    }
10717
10718    // =========================================================
10719    // BACKUP AND RESTORE
10720    // =========================================================
10721
10722    // Cause the target app to be launched if necessary and its backup agent
10723    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10724    // activity manager to announce its creation.
10725    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10726        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10727        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10728
10729        synchronized(this) {
10730            // !!! TODO: currently no check here that we're already bound
10731            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10732            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10733            synchronized (stats) {
10734                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10735            }
10736
10737            // Backup agent is now in use, its package can't be stopped.
10738            try {
10739                AppGlobals.getPackageManager().setPackageStoppedState(
10740                        app.packageName, false, UserHandle.getUserId(app.uid));
10741            } catch (RemoteException e) {
10742            } catch (IllegalArgumentException e) {
10743                Slog.w(TAG, "Failed trying to unstop package "
10744                        + app.packageName + ": " + e);
10745            }
10746
10747            BackupRecord r = new BackupRecord(ss, app, backupMode);
10748            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10749                    ? new ComponentName(app.packageName, app.backupAgentName)
10750                    : new ComponentName("android", "FullBackupAgent");
10751            // startProcessLocked() returns existing proc's record if it's already running
10752            ProcessRecord proc = startProcessLocked(app.processName, app,
10753                    false, 0, "backup", hostingName, false, false);
10754            if (proc == null) {
10755                Slog.e(TAG, "Unable to start backup agent process " + r);
10756                return false;
10757            }
10758
10759            r.app = proc;
10760            mBackupTarget = r;
10761            mBackupAppName = app.packageName;
10762
10763            // Try not to kill the process during backup
10764            updateOomAdjLocked(proc);
10765
10766            // If the process is already attached, schedule the creation of the backup agent now.
10767            // If it is not yet live, this will be done when it attaches to the framework.
10768            if (proc.thread != null) {
10769                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
10770                try {
10771                    proc.thread.scheduleCreateBackupAgent(app,
10772                            compatibilityInfoForPackageLocked(app), backupMode);
10773                } catch (RemoteException e) {
10774                    // Will time out on the backup manager side
10775                }
10776            } else {
10777                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
10778            }
10779            // Invariants: at this point, the target app process exists and the application
10780            // is either already running or in the process of coming up.  mBackupTarget and
10781            // mBackupAppName describe the app, so that when it binds back to the AM we
10782            // know that it's scheduled for a backup-agent operation.
10783        }
10784
10785        return true;
10786    }
10787
10788    // A backup agent has just come up
10789    public void backupAgentCreated(String agentPackageName, IBinder agent) {
10790        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
10791                + " = " + agent);
10792
10793        synchronized(this) {
10794            if (!agentPackageName.equals(mBackupAppName)) {
10795                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
10796                return;
10797            }
10798        }
10799
10800        long oldIdent = Binder.clearCallingIdentity();
10801        try {
10802            IBackupManager bm = IBackupManager.Stub.asInterface(
10803                    ServiceManager.getService(Context.BACKUP_SERVICE));
10804            bm.agentConnected(agentPackageName, agent);
10805        } catch (RemoteException e) {
10806            // can't happen; the backup manager service is local
10807        } catch (Exception e) {
10808            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10809            e.printStackTrace();
10810        } finally {
10811            Binder.restoreCallingIdentity(oldIdent);
10812        }
10813    }
10814
10815    // done with this agent
10816    public void unbindBackupAgent(ApplicationInfo appInfo) {
10817        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
10818        if (appInfo == null) {
10819            Slog.w(TAG, "unbind backup agent for null app");
10820            return;
10821        }
10822
10823        synchronized(this) {
10824            if (mBackupAppName == null) {
10825                Slog.w(TAG, "Unbinding backup agent with no active backup");
10826                return;
10827            }
10828
10829            if (!mBackupAppName.equals(appInfo.packageName)) {
10830                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
10831                return;
10832            }
10833
10834            ProcessRecord proc = mBackupTarget.app;
10835            mBackupTarget = null;
10836            mBackupAppName = null;
10837
10838            // Not backing this app up any more; reset its OOM adjustment
10839            updateOomAdjLocked(proc);
10840
10841            // If the app crashed during backup, 'thread' will be null here
10842            if (proc.thread != null) {
10843                try {
10844                    proc.thread.scheduleDestroyBackupAgent(appInfo,
10845                            compatibilityInfoForPackageLocked(appInfo));
10846                } catch (Exception e) {
10847                    Slog.e(TAG, "Exception when unbinding backup agent:");
10848                    e.printStackTrace();
10849                }
10850            }
10851        }
10852    }
10853    // =========================================================
10854    // BROADCASTS
10855    // =========================================================
10856
10857    private final List getStickiesLocked(String action, IntentFilter filter,
10858            List cur) {
10859        final ContentResolver resolver = mContext.getContentResolver();
10860        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10861        if (list == null) {
10862            return cur;
10863        }
10864        int N = list.size();
10865        for (int i=0; i<N; i++) {
10866            Intent intent = list.get(i);
10867            if (filter.match(resolver, intent, true, TAG) >= 0) {
10868                if (cur == null) {
10869                    cur = new ArrayList<Intent>();
10870                }
10871                cur.add(intent);
10872            }
10873        }
10874        return cur;
10875    }
10876
10877    boolean isPendingBroadcastProcessLocked(int pid) {
10878        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
10879                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
10880    }
10881
10882    void skipPendingBroadcastLocked(int pid) {
10883            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
10884            for (BroadcastQueue queue : mBroadcastQueues) {
10885                queue.skipPendingBroadcastLocked(pid);
10886            }
10887    }
10888
10889    // The app just attached; send any pending broadcasts that it should receive
10890    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
10891        boolean didSomething = false;
10892        for (BroadcastQueue queue : mBroadcastQueues) {
10893            didSomething |= queue.sendPendingBroadcastsLocked(app);
10894        }
10895        return didSomething;
10896    }
10897
10898    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
10899            IIntentReceiver receiver, IntentFilter filter, String permission) {
10900        enforceNotIsolatedCaller("registerReceiver");
10901        int callingUid;
10902        synchronized(this) {
10903            ProcessRecord callerApp = null;
10904            if (caller != null) {
10905                callerApp = getRecordForAppLocked(caller);
10906                if (callerApp == null) {
10907                    throw new SecurityException(
10908                            "Unable to find app for caller " + caller
10909                            + " (pid=" + Binder.getCallingPid()
10910                            + ") when registering receiver " + receiver);
10911                }
10912                if (callerApp.info.uid != Process.SYSTEM_UID &&
10913                        !callerApp.pkgList.contains(callerPackage)) {
10914                    throw new SecurityException("Given caller package " + callerPackage
10915                            + " is not running in process " + callerApp);
10916                }
10917                callingUid = callerApp.info.uid;
10918            } else {
10919                callerPackage = null;
10920                callingUid = Binder.getCallingUid();
10921            }
10922
10923            List allSticky = null;
10924
10925            // Look for any matching sticky broadcasts...
10926            Iterator actions = filter.actionsIterator();
10927            if (actions != null) {
10928                while (actions.hasNext()) {
10929                    String action = (String)actions.next();
10930                    allSticky = getStickiesLocked(action, filter, allSticky);
10931                }
10932            } else {
10933                allSticky = getStickiesLocked(null, filter, allSticky);
10934            }
10935
10936            // The first sticky in the list is returned directly back to
10937            // the client.
10938            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10939
10940            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
10941                    + ": " + sticky);
10942
10943            if (receiver == null) {
10944                return sticky;
10945            }
10946
10947            ReceiverList rl
10948                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10949            if (rl == null) {
10950                rl = new ReceiverList(this, callerApp,
10951                        Binder.getCallingPid(),
10952                        Binder.getCallingUid(), receiver);
10953                if (rl.app != null) {
10954                    rl.app.receivers.add(rl);
10955                } else {
10956                    try {
10957                        receiver.asBinder().linkToDeath(rl, 0);
10958                    } catch (RemoteException e) {
10959                        return sticky;
10960                    }
10961                    rl.linkedToDeath = true;
10962                }
10963                mRegisteredReceivers.put(receiver.asBinder(), rl);
10964            }
10965            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
10966                    permission, callingUid);
10967            rl.add(bf);
10968            if (!bf.debugCheck()) {
10969                Slog.w(TAG, "==> For Dynamic broadast");
10970            }
10971            mReceiverResolver.addFilter(bf);
10972
10973            // Enqueue broadcasts for all existing stickies that match
10974            // this filter.
10975            if (allSticky != null) {
10976                ArrayList receivers = new ArrayList();
10977                receivers.add(bf);
10978
10979                int N = allSticky.size();
10980                for (int i=0; i<N; i++) {
10981                    Intent intent = (Intent)allSticky.get(i);
10982                    BroadcastQueue queue = broadcastQueueForIntent(intent);
10983                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
10984                            null, -1, -1, null, receivers, null, 0, null, null,
10985                            false, true, true, false);
10986                    queue.enqueueParallelBroadcastLocked(r);
10987                    queue.scheduleBroadcastsLocked();
10988                }
10989            }
10990
10991            return sticky;
10992        }
10993    }
10994
10995    public void unregisterReceiver(IIntentReceiver receiver) {
10996        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
10997
10998        final long origId = Binder.clearCallingIdentity();
10999        try {
11000            boolean doTrim = false;
11001
11002            synchronized(this) {
11003                ReceiverList rl
11004                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11005                if (rl != null) {
11006                    if (rl.curBroadcast != null) {
11007                        BroadcastRecord r = rl.curBroadcast;
11008                        final boolean doNext = finishReceiverLocked(
11009                                receiver.asBinder(), r.resultCode, r.resultData,
11010                                r.resultExtras, r.resultAbort, true);
11011                        if (doNext) {
11012                            doTrim = true;
11013                            r.queue.processNextBroadcast(false);
11014                        }
11015                    }
11016
11017                    if (rl.app != null) {
11018                        rl.app.receivers.remove(rl);
11019                    }
11020                    removeReceiverLocked(rl);
11021                    if (rl.linkedToDeath) {
11022                        rl.linkedToDeath = false;
11023                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11024                    }
11025                }
11026            }
11027
11028            // If we actually concluded any broadcasts, we might now be able
11029            // to trim the recipients' apps from our working set
11030            if (doTrim) {
11031                trimApplications();
11032                return;
11033            }
11034
11035        } finally {
11036            Binder.restoreCallingIdentity(origId);
11037        }
11038    }
11039
11040    void removeReceiverLocked(ReceiverList rl) {
11041        mRegisteredReceivers.remove(rl.receiver.asBinder());
11042        int N = rl.size();
11043        for (int i=0; i<N; i++) {
11044            mReceiverResolver.removeFilter(rl.get(i));
11045        }
11046    }
11047
11048    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11049        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11050            ProcessRecord r = mLruProcesses.get(i);
11051            if (r.thread != null) {
11052                try {
11053                    r.thread.dispatchPackageBroadcast(cmd, packages);
11054                } catch (RemoteException ex) {
11055                }
11056            }
11057        }
11058    }
11059
11060    private final int broadcastIntentLocked(ProcessRecord callerApp,
11061            String callerPackage, Intent intent, String resolvedType,
11062            IIntentReceiver resultTo, int resultCode, String resultData,
11063            Bundle map, String requiredPermission,
11064            boolean ordered, boolean sticky, int callingPid, int callingUid,
11065            int userId) {
11066        intent = new Intent(intent);
11067
11068        // By default broadcasts do not go to stopped apps.
11069        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11070
11071        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11072            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11073            + " ordered=" + ordered + " userid=" + userId);
11074        if ((resultTo != null) && !ordered) {
11075            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11076        }
11077
11078        boolean onlySendToCaller = false;
11079
11080        // If the caller is trying to send this broadcast to a different
11081        // user, verify that is allowed.
11082        if (UserHandle.getUserId(callingUid) != userId) {
11083            if (checkComponentPermission(
11084                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
11085                    callingPid, callingUid, -1, true)
11086                    != PackageManager.PERMISSION_GRANTED) {
11087                if (checkComponentPermission(
11088                        android.Manifest.permission.INTERACT_ACROSS_USERS,
11089                        callingPid, callingUid, -1, true)
11090                        == PackageManager.PERMISSION_GRANTED) {
11091                    onlySendToCaller = true;
11092                } else {
11093                    String msg = "Permission Denial: " + intent.getAction()
11094                            + " broadcast from " + callerPackage
11095                            + " asks to send as user " + userId
11096                            + " but is calling from user " + UserHandle.getUserId(callingUid)
11097                            + "; this requires "
11098                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
11099                    Slog.w(TAG, msg);
11100                    throw new SecurityException(msg);
11101                }
11102            }
11103        }
11104
11105        // Handle special intents: if this broadcast is from the package
11106        // manager about a package being removed, we need to remove all of
11107        // its activities from the history stack.
11108        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11109                intent.getAction());
11110        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11111                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11112                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11113                || uidRemoved) {
11114            if (checkComponentPermission(
11115                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11116                    callingPid, callingUid, -1, true)
11117                    == PackageManager.PERMISSION_GRANTED) {
11118                if (uidRemoved) {
11119                    final Bundle intentExtras = intent.getExtras();
11120                    final int uid = intentExtras != null
11121                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11122                    if (uid >= 0) {
11123                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11124                        synchronized (bs) {
11125                            bs.removeUidStatsLocked(uid);
11126                        }
11127                    }
11128                } else {
11129                    // If resources are unvailble just force stop all
11130                    // those packages and flush the attribute cache as well.
11131                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11132                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11133                        if (list != null && (list.length > 0)) {
11134                            for (String pkg : list) {
11135                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11136                            }
11137                            sendPackageBroadcastLocked(
11138                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
11139                        }
11140                    } else {
11141                        Uri data = intent.getData();
11142                        String ssp;
11143                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11144                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11145                                forceStopPackageLocked(ssp,
11146                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11147                                        false, userId);
11148                            }
11149                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11150                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11151                                        new String[] {ssp});
11152                            }
11153                        }
11154                    }
11155                }
11156            } else {
11157                String msg = "Permission Denial: " + intent.getAction()
11158                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11159                        + ", uid=" + callingUid + ")"
11160                        + " requires "
11161                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11162                Slog.w(TAG, msg);
11163                throw new SecurityException(msg);
11164            }
11165
11166        // Special case for adding a package: by default turn on compatibility
11167        // mode.
11168        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11169            Uri data = intent.getData();
11170            String ssp;
11171            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11172                mCompatModePackages.handlePackageAddedLocked(ssp,
11173                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11174            }
11175        }
11176
11177        /*
11178         * If this is the time zone changed action, queue up a message that will reset the timezone
11179         * of all currently running processes. This message will get queued up before the broadcast
11180         * happens.
11181         */
11182        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11183            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11184        }
11185
11186        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11187            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11188        }
11189
11190        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11191            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11192            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11193        }
11194
11195        /*
11196         * Prevent non-system code (defined here to be non-persistent
11197         * processes) from sending protected broadcasts.
11198         */
11199        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11200            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11201            callingUid == 0) {
11202            // Always okay.
11203        } else if (callerApp == null || !callerApp.persistent) {
11204            try {
11205                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11206                        intent.getAction())) {
11207                    String msg = "Permission Denial: not allowed to send broadcast "
11208                            + intent.getAction() + " from pid="
11209                            + callingPid + ", uid=" + callingUid;
11210                    Slog.w(TAG, msg);
11211                    throw new SecurityException(msg);
11212                }
11213            } catch (RemoteException e) {
11214                Slog.w(TAG, "Remote exception", e);
11215                return ActivityManager.BROADCAST_SUCCESS;
11216            }
11217        }
11218
11219        // Add to the sticky list if requested.
11220        if (sticky) {
11221            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11222                    callingPid, callingUid)
11223                    != PackageManager.PERMISSION_GRANTED) {
11224                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11225                        + callingPid + ", uid=" + callingUid
11226                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11227                Slog.w(TAG, msg);
11228                throw new SecurityException(msg);
11229            }
11230            if (requiredPermission != null) {
11231                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11232                        + " and enforce permission " + requiredPermission);
11233                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11234            }
11235            if (intent.getComponent() != null) {
11236                throw new SecurityException(
11237                        "Sticky broadcasts can't target a specific component");
11238            }
11239            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11240            if (list == null) {
11241                list = new ArrayList<Intent>();
11242                mStickyBroadcasts.put(intent.getAction(), list);
11243            }
11244            int N = list.size();
11245            int i;
11246            for (i=0; i<N; i++) {
11247                if (intent.filterEquals(list.get(i))) {
11248                    // This sticky already exists, replace it.
11249                    list.set(i, new Intent(intent));
11250                    break;
11251                }
11252            }
11253            if (i >= N) {
11254                list.add(new Intent(intent));
11255            }
11256        }
11257
11258        // Figure out who all will receive this broadcast.
11259        List receivers = null;
11260        List<BroadcastFilter> registeredReceivers = null;
11261        try {
11262            // Need to resolve the intent to interested receivers...
11263            if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11264                     == 0) {
11265                receivers = AppGlobals.getPackageManager().queryIntentReceivers(
11266                        intent, resolvedType, STOCK_PM_FLAGS, userId);
11267            }
11268            if (intent.getComponent() == null) {
11269                registeredReceivers = mReceiverResolver.queryIntent(intent,
11270                        resolvedType, false, userId);
11271            }
11272        } catch (RemoteException ex) {
11273            // pm is in same process, this will never happen.
11274        }
11275
11276        final boolean replacePending =
11277                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11278
11279        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11280                + " replacePending=" + replacePending);
11281
11282        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11283        if (!ordered && NR > 0) {
11284            // If we are not serializing this broadcast, then send the
11285            // registered receivers separately so they don't wait for the
11286            // components to be launched.
11287            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11288            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11289                    callerPackage, callingPid, callingUid, requiredPermission,
11290                    registeredReceivers, resultTo, resultCode, resultData, map,
11291                    ordered, sticky, false, onlySendToCaller);
11292            if (DEBUG_BROADCAST) Slog.v(
11293                    TAG, "Enqueueing parallel broadcast " + r);
11294            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11295            if (!replaced) {
11296                queue.enqueueParallelBroadcastLocked(r);
11297                queue.scheduleBroadcastsLocked();
11298            }
11299            registeredReceivers = null;
11300            NR = 0;
11301        }
11302
11303        // Merge into one list.
11304        int ir = 0;
11305        if (receivers != null) {
11306            // A special case for PACKAGE_ADDED: do not allow the package
11307            // being added to see this broadcast.  This prevents them from
11308            // using this as a back door to get run as soon as they are
11309            // installed.  Maybe in the future we want to have a special install
11310            // broadcast or such for apps, but we'd like to deliberately make
11311            // this decision.
11312            String skipPackages[] = null;
11313            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11314                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11315                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11316                Uri data = intent.getData();
11317                if (data != null) {
11318                    String pkgName = data.getSchemeSpecificPart();
11319                    if (pkgName != null) {
11320                        skipPackages = new String[] { pkgName };
11321                    }
11322                }
11323            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11324                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11325            }
11326            if (skipPackages != null && (skipPackages.length > 0)) {
11327                for (String skipPackage : skipPackages) {
11328                    if (skipPackage != null) {
11329                        int NT = receivers.size();
11330                        for (int it=0; it<NT; it++) {
11331                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11332                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11333                                receivers.remove(it);
11334                                it--;
11335                                NT--;
11336                            }
11337                        }
11338                    }
11339                }
11340            }
11341
11342            int NT = receivers != null ? receivers.size() : 0;
11343            int it = 0;
11344            ResolveInfo curt = null;
11345            BroadcastFilter curr = null;
11346            while (it < NT && ir < NR) {
11347                if (curt == null) {
11348                    curt = (ResolveInfo)receivers.get(it);
11349                }
11350                if (curr == null) {
11351                    curr = registeredReceivers.get(ir);
11352                }
11353                if (curr.getPriority() >= curt.priority) {
11354                    // Insert this broadcast record into the final list.
11355                    receivers.add(it, curr);
11356                    ir++;
11357                    curr = null;
11358                    it++;
11359                    NT++;
11360                } else {
11361                    // Skip to the next ResolveInfo in the final list.
11362                    it++;
11363                    curt = null;
11364                }
11365            }
11366        }
11367        while (ir < NR) {
11368            if (receivers == null) {
11369                receivers = new ArrayList();
11370            }
11371            receivers.add(registeredReceivers.get(ir));
11372            ir++;
11373        }
11374
11375        if ((receivers != null && receivers.size() > 0)
11376                || resultTo != null) {
11377            BroadcastQueue queue = broadcastQueueForIntent(intent);
11378            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11379                    callerPackage, callingPid, callingUid, requiredPermission,
11380                    receivers, resultTo, resultCode, resultData, map, ordered,
11381                    sticky, false, onlySendToCaller);
11382            if (DEBUG_BROADCAST) Slog.v(
11383                    TAG, "Enqueueing ordered broadcast " + r
11384                    + ": prev had " + queue.mOrderedBroadcasts.size());
11385            if (DEBUG_BROADCAST) {
11386                int seq = r.intent.getIntExtra("seq", -1);
11387                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11388            }
11389            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11390            if (!replaced) {
11391                queue.enqueueOrderedBroadcastLocked(r);
11392                queue.scheduleBroadcastsLocked();
11393            }
11394        }
11395
11396        return ActivityManager.BROADCAST_SUCCESS;
11397    }
11398
11399    final Intent verifyBroadcastLocked(Intent intent) {
11400        // Refuse possible leaked file descriptors
11401        if (intent != null && intent.hasFileDescriptors() == true) {
11402            throw new IllegalArgumentException("File descriptors passed in Intent");
11403        }
11404
11405        int flags = intent.getFlags();
11406
11407        if (!mProcessesReady) {
11408            // if the caller really truly claims to know what they're doing, go
11409            // ahead and allow the broadcast without launching any receivers
11410            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11411                intent = new Intent(intent);
11412                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11413            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11414                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11415                        + " before boot completion");
11416                throw new IllegalStateException("Cannot broadcast before boot completed");
11417            }
11418        }
11419
11420        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11421            throw new IllegalArgumentException(
11422                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11423        }
11424
11425        return intent;
11426    }
11427
11428    public final int broadcastIntent(IApplicationThread caller,
11429            Intent intent, String resolvedType, IIntentReceiver resultTo,
11430            int resultCode, String resultData, Bundle map,
11431            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11432        enforceNotIsolatedCaller("broadcastIntent");
11433        synchronized(this) {
11434            intent = verifyBroadcastLocked(intent);
11435
11436            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11437            final int callingPid = Binder.getCallingPid();
11438            final int callingUid = Binder.getCallingUid();
11439            final long origId = Binder.clearCallingIdentity();
11440            int res = broadcastIntentLocked(callerApp,
11441                    callerApp != null ? callerApp.info.packageName : null,
11442                    intent, resolvedType, resultTo,
11443                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11444                    callingPid, callingUid, userId);
11445            Binder.restoreCallingIdentity(origId);
11446            return res;
11447        }
11448    }
11449
11450    int broadcastIntentInPackage(String packageName, int uid,
11451            Intent intent, String resolvedType, IIntentReceiver resultTo,
11452            int resultCode, String resultData, Bundle map,
11453            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11454        synchronized(this) {
11455            intent = verifyBroadcastLocked(intent);
11456
11457            final long origId = Binder.clearCallingIdentity();
11458            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11459                    resultTo, resultCode, resultData, map, requiredPermission,
11460                    serialized, sticky, -1, uid, userId);
11461            Binder.restoreCallingIdentity(origId);
11462            return res;
11463        }
11464    }
11465
11466    // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
11467    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11468        // Refuse possible leaked file descriptors
11469        if (intent != null && intent.hasFileDescriptors() == true) {
11470            throw new IllegalArgumentException("File descriptors passed in Intent");
11471        }
11472
11473        synchronized(this) {
11474            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11475                    != PackageManager.PERMISSION_GRANTED) {
11476                String msg = "Permission Denial: unbroadcastIntent() from pid="
11477                        + Binder.getCallingPid()
11478                        + ", uid=" + Binder.getCallingUid()
11479                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11480                Slog.w(TAG, msg);
11481                throw new SecurityException(msg);
11482            }
11483            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11484            if (list != null) {
11485                int N = list.size();
11486                int i;
11487                for (i=0; i<N; i++) {
11488                    if (intent.filterEquals(list.get(i))) {
11489                        list.remove(i);
11490                        break;
11491                    }
11492                }
11493            }
11494        }
11495    }
11496
11497    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11498            String resultData, Bundle resultExtras, boolean resultAbort,
11499            boolean explicit) {
11500        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11501        if (r == null) {
11502            Slog.w(TAG, "finishReceiver called but not found on queue");
11503            return false;
11504        }
11505
11506        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11507                explicit);
11508    }
11509
11510    public void finishReceiver(IBinder who, int resultCode, String resultData,
11511            Bundle resultExtras, boolean resultAbort) {
11512        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11513
11514        // Refuse possible leaked file descriptors
11515        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11516            throw new IllegalArgumentException("File descriptors passed in Bundle");
11517        }
11518
11519        final long origId = Binder.clearCallingIdentity();
11520        try {
11521            boolean doNext = false;
11522            BroadcastRecord r = null;
11523
11524            synchronized(this) {
11525                r = broadcastRecordForReceiverLocked(who);
11526                if (r != null) {
11527                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11528                        resultData, resultExtras, resultAbort, true);
11529                }
11530            }
11531
11532            if (doNext) {
11533                r.queue.processNextBroadcast(false);
11534            }
11535            trimApplications();
11536        } finally {
11537            Binder.restoreCallingIdentity(origId);
11538        }
11539    }
11540
11541    // =========================================================
11542    // INSTRUMENTATION
11543    // =========================================================
11544
11545    public boolean startInstrumentation(ComponentName className,
11546            String profileFile, int flags, Bundle arguments,
11547            IInstrumentationWatcher watcher) {
11548        enforceNotIsolatedCaller("startInstrumentation");
11549        // Refuse possible leaked file descriptors
11550        if (arguments != null && arguments.hasFileDescriptors()) {
11551            throw new IllegalArgumentException("File descriptors passed in Bundle");
11552        }
11553
11554        synchronized(this) {
11555            InstrumentationInfo ii = null;
11556            ApplicationInfo ai = null;
11557            try {
11558                ii = mContext.getPackageManager().getInstrumentationInfo(
11559                    className, STOCK_PM_FLAGS);
11560                ai = mContext.getPackageManager().getApplicationInfo(
11561                        ii.targetPackage, STOCK_PM_FLAGS);
11562            } catch (PackageManager.NameNotFoundException e) {
11563            }
11564            if (ii == null) {
11565                reportStartInstrumentationFailure(watcher, className,
11566                        "Unable to find instrumentation info for: " + className);
11567                return false;
11568            }
11569            if (ai == null) {
11570                reportStartInstrumentationFailure(watcher, className,
11571                        "Unable to find instrumentation target package: " + ii.targetPackage);
11572                return false;
11573            }
11574
11575            int match = mContext.getPackageManager().checkSignatures(
11576                    ii.targetPackage, ii.packageName);
11577            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11578                String msg = "Permission Denial: starting instrumentation "
11579                        + className + " from pid="
11580                        + Binder.getCallingPid()
11581                        + ", uid=" + Binder.getCallingPid()
11582                        + " not allowed because package " + ii.packageName
11583                        + " does not have a signature matching the target "
11584                        + ii.targetPackage;
11585                reportStartInstrumentationFailure(watcher, className, msg);
11586                throw new SecurityException(msg);
11587            }
11588
11589            int userId = UserHandle.getCallingUserId();
11590            final long origId = Binder.clearCallingIdentity();
11591            // Instrumentation can kill and relaunch even persistent processes
11592            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
11593            ProcessRecord app = addAppLocked(ai, false);
11594            app.instrumentationClass = className;
11595            app.instrumentationInfo = ai;
11596            app.instrumentationProfileFile = profileFile;
11597            app.instrumentationArguments = arguments;
11598            app.instrumentationWatcher = watcher;
11599            app.instrumentationResultClass = className;
11600            Binder.restoreCallingIdentity(origId);
11601        }
11602
11603        return true;
11604    }
11605
11606    /**
11607     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11608     * error to the logs, but if somebody is watching, send the report there too.  This enables
11609     * the "am" command to report errors with more information.
11610     *
11611     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11612     * @param cn The component name of the instrumentation.
11613     * @param report The error report.
11614     */
11615    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11616            ComponentName cn, String report) {
11617        Slog.w(TAG, report);
11618        try {
11619            if (watcher != null) {
11620                Bundle results = new Bundle();
11621                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11622                results.putString("Error", report);
11623                watcher.instrumentationStatus(cn, -1, results);
11624            }
11625        } catch (RemoteException e) {
11626            Slog.w(TAG, e);
11627        }
11628    }
11629
11630    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11631        if (app.instrumentationWatcher != null) {
11632            try {
11633                // NOTE:  IInstrumentationWatcher *must* be oneway here
11634                app.instrumentationWatcher.instrumentationFinished(
11635                    app.instrumentationClass,
11636                    resultCode,
11637                    results);
11638            } catch (RemoteException e) {
11639            }
11640        }
11641        app.instrumentationWatcher = null;
11642        app.instrumentationClass = null;
11643        app.instrumentationInfo = null;
11644        app.instrumentationProfileFile = null;
11645        app.instrumentationArguments = null;
11646
11647        forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId);
11648    }
11649
11650    public void finishInstrumentation(IApplicationThread target,
11651            int resultCode, Bundle results) {
11652        int userId = UserHandle.getCallingUserId();
11653        // Refuse possible leaked file descriptors
11654        if (results != null && results.hasFileDescriptors()) {
11655            throw new IllegalArgumentException("File descriptors passed in Intent");
11656        }
11657
11658        synchronized(this) {
11659            ProcessRecord app = getRecordForAppLocked(target);
11660            if (app == null) {
11661                Slog.w(TAG, "finishInstrumentation: no app for " + target);
11662                return;
11663            }
11664            final long origId = Binder.clearCallingIdentity();
11665            finishInstrumentationLocked(app, resultCode, results);
11666            Binder.restoreCallingIdentity(origId);
11667        }
11668    }
11669
11670    // =========================================================
11671    // CONFIGURATION
11672    // =========================================================
11673
11674    public ConfigurationInfo getDeviceConfigurationInfo() {
11675        ConfigurationInfo config = new ConfigurationInfo();
11676        synchronized (this) {
11677            config.reqTouchScreen = mConfiguration.touchscreen;
11678            config.reqKeyboardType = mConfiguration.keyboard;
11679            config.reqNavigation = mConfiguration.navigation;
11680            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11681                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
11682                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11683            }
11684            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11685                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
11686                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11687            }
11688            config.reqGlEsVersion = GL_ES_VERSION;
11689        }
11690        return config;
11691    }
11692
11693    public Configuration getConfiguration() {
11694        Configuration ci;
11695        synchronized(this) {
11696            ci = new Configuration(mConfiguration);
11697        }
11698        return ci;
11699    }
11700
11701    public void updatePersistentConfiguration(Configuration values) {
11702        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11703                "updateConfiguration()");
11704        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
11705                "updateConfiguration()");
11706        if (values == null) {
11707            throw new NullPointerException("Configuration must not be null");
11708        }
11709
11710        synchronized(this) {
11711            final long origId = Binder.clearCallingIdentity();
11712            updateConfigurationLocked(values, null, true, false);
11713            Binder.restoreCallingIdentity(origId);
11714        }
11715    }
11716
11717    public void updateConfiguration(Configuration values) {
11718        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11719                "updateConfiguration()");
11720
11721        synchronized(this) {
11722            if (values == null && mWindowManager != null) {
11723                // sentinel: fetch the current configuration from the window manager
11724                values = mWindowManager.computeNewConfiguration();
11725            }
11726
11727            if (mWindowManager != null) {
11728                mProcessList.applyDisplaySize(mWindowManager);
11729            }
11730
11731            final long origId = Binder.clearCallingIdentity();
11732            if (values != null) {
11733                Settings.System.clearConfiguration(values);
11734            }
11735            updateConfigurationLocked(values, null, false, false);
11736            Binder.restoreCallingIdentity(origId);
11737        }
11738    }
11739
11740    /**
11741     * Do either or both things: (1) change the current configuration, and (2)
11742     * make sure the given activity is running with the (now) current
11743     * configuration.  Returns true if the activity has been left running, or
11744     * false if <var>starting</var> is being destroyed to match the new
11745     * configuration.
11746     * @param persistent TODO
11747     */
11748    boolean updateConfigurationLocked(Configuration values,
11749            ActivityRecord starting, boolean persistent, boolean initLocale) {
11750        // do nothing if we are headless
11751        if (mHeadless) return true;
11752
11753        int changes = 0;
11754
11755        boolean kept = true;
11756
11757        if (values != null) {
11758            Configuration newConfig = new Configuration(mConfiguration);
11759            changes = newConfig.updateFrom(values);
11760            if (changes != 0) {
11761                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
11762                    Slog.i(TAG, "Updating configuration to: " + values);
11763                }
11764
11765                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
11766
11767                if (values.locale != null && !initLocale) {
11768                    saveLocaleLocked(values.locale,
11769                                     !values.locale.equals(mConfiguration.locale),
11770                                     values.userSetLocale);
11771                }
11772
11773                mConfigurationSeq++;
11774                if (mConfigurationSeq <= 0) {
11775                    mConfigurationSeq = 1;
11776                }
11777                newConfig.seq = mConfigurationSeq;
11778                mConfiguration = newConfig;
11779                Slog.i(TAG, "Config changed: " + newConfig);
11780
11781                final Configuration configCopy = new Configuration(mConfiguration);
11782
11783                // TODO: If our config changes, should we auto dismiss any currently
11784                // showing dialogs?
11785                mShowDialogs = shouldShowDialogs(newConfig);
11786
11787                AttributeCache ac = AttributeCache.instance();
11788                if (ac != null) {
11789                    ac.updateConfiguration(configCopy);
11790                }
11791
11792                // Make sure all resources in our process are updated
11793                // right now, so that anyone who is going to retrieve
11794                // resource values after we return will be sure to get
11795                // the new ones.  This is especially important during
11796                // boot, where the first config change needs to guarantee
11797                // all resources have that config before following boot
11798                // code is executed.
11799                mSystemThread.applyConfigurationToResources(configCopy);
11800
11801                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
11802                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
11803                    msg.obj = new Configuration(configCopy);
11804                    mHandler.sendMessage(msg);
11805                }
11806
11807                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11808                    ProcessRecord app = mLruProcesses.get(i);
11809                    try {
11810                        if (app.thread != null) {
11811                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
11812                                    + app.processName + " new config " + mConfiguration);
11813                            app.thread.scheduleConfigurationChanged(configCopy);
11814                        }
11815                    } catch (Exception e) {
11816                    }
11817                }
11818                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
11819                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11820                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
11821                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
11822                        null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11823                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
11824                    broadcastIntentLocked(null, null,
11825                            new Intent(Intent.ACTION_LOCALE_CHANGED),
11826                            null, null, 0, null, null,
11827                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11828                }
11829            }
11830        }
11831
11832        if (changes != 0 && starting == null) {
11833            // If the configuration changed, and the caller is not already
11834            // in the process of starting an activity, then find the top
11835            // activity to check if its configuration needs to change.
11836            starting = mMainStack.topRunningActivityLocked(null);
11837        }
11838
11839        if (starting != null) {
11840            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
11841            // And we need to make sure at this point that all other activities
11842            // are made visible with the correct configuration.
11843            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
11844        }
11845
11846        if (values != null && mWindowManager != null) {
11847            mWindowManager.setNewConfiguration(mConfiguration);
11848        }
11849
11850        return kept;
11851    }
11852
11853    /**
11854     * Decide based on the configuration whether we should shouw the ANR,
11855     * crash, etc dialogs.  The idea is that if there is no affordnace to
11856     * press the on-screen buttons, we shouldn't show the dialog.
11857     *
11858     * A thought: SystemUI might also want to get told about this, the Power
11859     * dialog / global actions also might want different behaviors.
11860     */
11861    private static final boolean shouldShowDialogs(Configuration config) {
11862        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
11863                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
11864    }
11865
11866    /**
11867     * Save the locale.  You must be inside a synchronized (this) block.
11868     */
11869    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
11870        if(isDiff) {
11871            SystemProperties.set("user.language", l.getLanguage());
11872            SystemProperties.set("user.region", l.getCountry());
11873        }
11874
11875        if(isPersist) {
11876            SystemProperties.set("persist.sys.language", l.getLanguage());
11877            SystemProperties.set("persist.sys.country", l.getCountry());
11878            SystemProperties.set("persist.sys.localevar", l.getVariant());
11879        }
11880    }
11881
11882    @Override
11883    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
11884        ActivityRecord srec = ActivityRecord.forToken(token);
11885        return srec != null && srec.task.affinity != null &&
11886                srec.task.affinity.equals(destAffinity);
11887    }
11888
11889    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
11890            Intent resultData) {
11891        ComponentName dest = destIntent.getComponent();
11892
11893        synchronized (this) {
11894            ActivityRecord srec = ActivityRecord.forToken(token);
11895            if (srec == null) {
11896                return false;
11897            }
11898            ArrayList<ActivityRecord> history = srec.stack.mHistory;
11899            final int start = history.indexOf(srec);
11900            if (start < 0) {
11901                // Current activity is not in history stack; do nothing.
11902                return false;
11903            }
11904            int finishTo = start - 1;
11905            ActivityRecord parent = null;
11906            boolean foundParentInTask = false;
11907            if (dest != null) {
11908                TaskRecord tr = srec.task;
11909                for (int i = start - 1; i >= 0; i--) {
11910                    ActivityRecord r = history.get(i);
11911                    if (tr != r.task) {
11912                        // Couldn't find parent in the same task; stop at the one above this.
11913                        // (Root of current task; in-app "home" behavior)
11914                        // Always at least finish the current activity.
11915                        finishTo = Math.min(start - 1, i + 1);
11916                        parent = history.get(finishTo);
11917                        break;
11918                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
11919                            r.info.name.equals(dest.getClassName())) {
11920                        finishTo = i;
11921                        parent = r;
11922                        foundParentInTask = true;
11923                        break;
11924                    }
11925                }
11926            }
11927
11928            if (mController != null) {
11929                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
11930                if (next != null) {
11931                    // ask watcher if this is allowed
11932                    boolean resumeOK = true;
11933                    try {
11934                        resumeOK = mController.activityResuming(next.packageName);
11935                    } catch (RemoteException e) {
11936                        mController = null;
11937                    }
11938
11939                    if (!resumeOK) {
11940                        return false;
11941                    }
11942                }
11943            }
11944            final long origId = Binder.clearCallingIdentity();
11945            for (int i = start; i > finishTo; i--) {
11946                ActivityRecord r = history.get(i);
11947                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
11948                        "navigate-up");
11949                // Only return the supplied result for the first activity finished
11950                resultCode = Activity.RESULT_CANCELED;
11951                resultData = null;
11952            }
11953
11954            if (parent != null && foundParentInTask) {
11955                final int parentLaunchMode = parent.info.launchMode;
11956                final int destIntentFlags = destIntent.getFlags();
11957                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
11958                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
11959                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
11960                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
11961                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
11962                } else {
11963                    try {
11964                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
11965                                destIntent.getComponent(), 0, UserHandle.getCallingUserId());
11966                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
11967                                null, aInfo, parent.appToken, null,
11968                                0, -1, parent.launchedFromUid, 0, null, true, null);
11969                        foundParentInTask = res == ActivityManager.START_SUCCESS;
11970                    } catch (RemoteException e) {
11971                        foundParentInTask = false;
11972                    }
11973                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
11974                            resultData, "navigate-up");
11975                }
11976            }
11977            Binder.restoreCallingIdentity(origId);
11978            return foundParentInTask;
11979        }
11980    }
11981
11982    public int getLaunchedFromUid(IBinder activityToken) {
11983        ActivityRecord srec = ActivityRecord.forToken(activityToken);
11984        if (srec == null) {
11985            return -1;
11986        }
11987        return srec.launchedFromUid;
11988    }
11989
11990    // =========================================================
11991    // LIFETIME MANAGEMENT
11992    // =========================================================
11993
11994    // Returns which broadcast queue the app is the current [or imminent] receiver
11995    // on, or 'null' if the app is not an active broadcast recipient.
11996    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
11997        BroadcastRecord r = app.curReceiver;
11998        if (r != null) {
11999            return r.queue;
12000        }
12001
12002        // It's not the current receiver, but it might be starting up to become one
12003        synchronized (this) {
12004            for (BroadcastQueue queue : mBroadcastQueues) {
12005                r = queue.mPendingBroadcast;
12006                if (r != null && r.curApp == app) {
12007                    // found it; report which queue it's in
12008                    return queue;
12009                }
12010            }
12011        }
12012
12013        return null;
12014    }
12015
12016    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12017            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12018        if (mAdjSeq == app.adjSeq) {
12019            // This adjustment has already been computed.  If we are calling
12020            // from the top, we may have already computed our adjustment with
12021            // an earlier hidden adjustment that isn't really for us... if
12022            // so, use the new hidden adjustment.
12023            if (!recursed && app.hidden) {
12024                app.curAdj = app.curRawAdj = app.nonStoppingAdj =
12025                        app.hasActivities ? hiddenAdj : emptyAdj;
12026            }
12027            return app.curRawAdj;
12028        }
12029
12030        if (app.thread == null) {
12031            app.adjSeq = mAdjSeq;
12032            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12033            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12034        }
12035
12036        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12037        app.adjSource = null;
12038        app.adjTarget = null;
12039        app.empty = false;
12040        app.hidden = false;
12041
12042        final int activitiesSize = app.activities.size();
12043
12044        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12045            // The max adjustment doesn't allow this app to be anything
12046            // below foreground, so it is not worth doing work for it.
12047            app.adjType = "fixed";
12048            app.adjSeq = mAdjSeq;
12049            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12050            app.hasActivities = false;
12051            app.foregroundActivities = false;
12052            app.keeping = true;
12053            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12054            // System process can do UI, and when they do we want to have
12055            // them trim their memory after the user leaves the UI.  To
12056            // facilitate this, here we need to determine whether or not it
12057            // is currently showing UI.
12058            app.systemNoUi = true;
12059            if (app == TOP_APP) {
12060                app.systemNoUi = false;
12061                app.hasActivities = true;
12062            } else if (activitiesSize > 0) {
12063                for (int j = 0; j < activitiesSize; j++) {
12064                    final ActivityRecord r = app.activities.get(j);
12065                    if (r.visible) {
12066                        app.systemNoUi = false;
12067                    }
12068                    if (r.app == app) {
12069                        app.hasActivities = true;
12070                    }
12071                }
12072            }
12073            return (app.curAdj=app.maxAdj);
12074        }
12075
12076        app.keeping = false;
12077        app.systemNoUi = false;
12078        app.hasActivities = false;
12079
12080        // Determine the importance of the process, starting with most
12081        // important to least, and assign an appropriate OOM adjustment.
12082        int adj;
12083        int schedGroup;
12084        boolean foregroundActivities = false;
12085        boolean interesting = false;
12086        BroadcastQueue queue;
12087        if (app == TOP_APP) {
12088            // The last app on the list is the foreground app.
12089            adj = ProcessList.FOREGROUND_APP_ADJ;
12090            schedGroup = Process.THREAD_GROUP_DEFAULT;
12091            app.adjType = "top-activity";
12092            foregroundActivities = true;
12093            interesting = true;
12094            app.hasActivities = true;
12095        } else if (app.instrumentationClass != null) {
12096            // Don't want to kill running instrumentation.
12097            adj = ProcessList.FOREGROUND_APP_ADJ;
12098            schedGroup = Process.THREAD_GROUP_DEFAULT;
12099            app.adjType = "instrumentation";
12100            interesting = true;
12101        } else if ((queue = isReceivingBroadcast(app)) != null) {
12102            // An app that is currently receiving a broadcast also
12103            // counts as being in the foreground for OOM killer purposes.
12104            // It's placed in a sched group based on the nature of the
12105            // broadcast as reflected by which queue it's active in.
12106            adj = ProcessList.FOREGROUND_APP_ADJ;
12107            schedGroup = (queue == mFgBroadcastQueue)
12108                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12109            app.adjType = "broadcast";
12110        } else if (app.executingServices.size() > 0) {
12111            // An app that is currently executing a service callback also
12112            // counts as being in the foreground.
12113            adj = ProcessList.FOREGROUND_APP_ADJ;
12114            schedGroup = Process.THREAD_GROUP_DEFAULT;
12115            app.adjType = "exec-service";
12116        } else {
12117            // Assume process is hidden (has activities); we will correct
12118            // later if this is not the case.
12119            adj = hiddenAdj;
12120            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12121            app.hidden = true;
12122            app.adjType = "bg-activities";
12123        }
12124
12125        boolean hasStoppingActivities = false;
12126
12127        // Examine all activities if not already foreground.
12128        if (!foregroundActivities && activitiesSize > 0) {
12129            for (int j = 0; j < activitiesSize; j++) {
12130                final ActivityRecord r = app.activities.get(j);
12131                if (r.visible) {
12132                    // App has a visible activity; only upgrade adjustment.
12133                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12134                        adj = ProcessList.VISIBLE_APP_ADJ;
12135                        app.adjType = "visible";
12136                    }
12137                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12138                    app.hidden = false;
12139                    app.hasActivities = true;
12140                    foregroundActivities = true;
12141                    break;
12142                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12143                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12144                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12145                        app.adjType = "pausing";
12146                    }
12147                    app.hidden = false;
12148                    foregroundActivities = true;
12149                } else if (r.state == ActivityState.STOPPING) {
12150                    // We will apply the actual adjustment later, because
12151                    // we want to allow this process to immediately go through
12152                    // any memory trimming that is in effect.
12153                    app.hidden = false;
12154                    foregroundActivities = true;
12155                    hasStoppingActivities = true;
12156                }
12157                if (r.app == app) {
12158                    app.hasActivities = true;
12159                }
12160            }
12161        }
12162
12163        if (adj == hiddenAdj && !app.hasActivities) {
12164            // Whoops, this process is completely empty as far as we know
12165            // at this point.
12166            adj = emptyAdj;
12167            app.empty = true;
12168            app.adjType = "bg-empty";
12169        }
12170
12171        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12172            if (app.foregroundServices) {
12173                // The user is aware of this app, so make it visible.
12174                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12175                app.hidden = false;
12176                app.adjType = "foreground-service";
12177                schedGroup = Process.THREAD_GROUP_DEFAULT;
12178            } else if (app.forcingToForeground != null) {
12179                // The user is aware of this app, so make it visible.
12180                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12181                app.hidden = false;
12182                app.adjType = "force-foreground";
12183                app.adjSource = app.forcingToForeground;
12184                schedGroup = Process.THREAD_GROUP_DEFAULT;
12185            }
12186        }
12187
12188        if (app.foregroundServices) {
12189            interesting = true;
12190        }
12191
12192        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12193            // We don't want to kill the current heavy-weight process.
12194            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12195            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12196            app.hidden = false;
12197            app.adjType = "heavy";
12198        }
12199
12200        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12201            // This process is hosting what we currently consider to be the
12202            // home app, so we don't want to let it go into the background.
12203            adj = ProcessList.HOME_APP_ADJ;
12204            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12205            app.hidden = false;
12206            app.adjType = "home";
12207        }
12208
12209        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12210                && app.activities.size() > 0) {
12211            // This was the previous process that showed UI to the user.
12212            // We want to try to keep it around more aggressively, to give
12213            // a good experience around switching between two apps.
12214            adj = ProcessList.PREVIOUS_APP_ADJ;
12215            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12216            app.hidden = false;
12217            app.adjType = "previous";
12218        }
12219
12220        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12221                + " reason=" + app.adjType);
12222
12223        // By default, we use the computed adjustment.  It may be changed if
12224        // there are applications dependent on our services or providers, but
12225        // this gives us a baseline and makes sure we don't get into an
12226        // infinite recursion.
12227        app.adjSeq = mAdjSeq;
12228        app.curRawAdj = app.nonStoppingAdj = adj;
12229
12230        if (mBackupTarget != null && app == mBackupTarget.app) {
12231            // If possible we want to avoid killing apps while they're being backed up
12232            if (adj > ProcessList.BACKUP_APP_ADJ) {
12233                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12234                adj = ProcessList.BACKUP_APP_ADJ;
12235                app.adjType = "backup";
12236                app.hidden = false;
12237            }
12238        }
12239
12240        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12241                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12242            final long now = SystemClock.uptimeMillis();
12243            // This process is more important if the top activity is
12244            // bound to the service.
12245            Iterator<ServiceRecord> jt = app.services.iterator();
12246            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12247                ServiceRecord s = jt.next();
12248                if (s.startRequested) {
12249                    if (app.hasShownUi && app != mHomeProcess) {
12250                        // If this process has shown some UI, let it immediately
12251                        // go to the LRU list because it may be pretty heavy with
12252                        // UI stuff.  We'll tag it with a label just to help
12253                        // debug and understand what is going on.
12254                        if (adj > ProcessList.SERVICE_ADJ) {
12255                            app.adjType = "started-bg-ui-services";
12256                        }
12257                    } else {
12258                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12259                            // This service has seen some activity within
12260                            // recent memory, so we will keep its process ahead
12261                            // of the background processes.
12262                            if (adj > ProcessList.SERVICE_ADJ) {
12263                                adj = ProcessList.SERVICE_ADJ;
12264                                app.adjType = "started-services";
12265                                app.hidden = false;
12266                            }
12267                        }
12268                        // If we have let the service slide into the background
12269                        // state, still have some text describing what it is doing
12270                        // even though the service no longer has an impact.
12271                        if (adj > ProcessList.SERVICE_ADJ) {
12272                            app.adjType = "started-bg-services";
12273                        }
12274                    }
12275                    // Don't kill this process because it is doing work; it
12276                    // has said it is doing work.
12277                    app.keeping = true;
12278                }
12279                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12280                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12281                    Iterator<ArrayList<ConnectionRecord>> kt
12282                            = s.connections.values().iterator();
12283                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12284                        ArrayList<ConnectionRecord> clist = kt.next();
12285                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12286                            // XXX should compute this based on the max of
12287                            // all connected clients.
12288                            ConnectionRecord cr = clist.get(i);
12289                            if (cr.binding.client == app) {
12290                                // Binding to ourself is not interesting.
12291                                continue;
12292                            }
12293                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12294                                ProcessRecord client = cr.binding.client;
12295                                int clientAdj = adj;
12296                                int myHiddenAdj = hiddenAdj;
12297                                if (myHiddenAdj > client.hiddenAdj) {
12298                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12299                                        myHiddenAdj = client.hiddenAdj;
12300                                    } else {
12301                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12302                                    }
12303                                }
12304                                int myEmptyAdj = emptyAdj;
12305                                if (myEmptyAdj > client.emptyAdj) {
12306                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12307                                        myEmptyAdj = client.emptyAdj;
12308                                    } else {
12309                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12310                                    }
12311                                }
12312                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12313                                        myEmptyAdj, TOP_APP, true, doingAll);
12314                                String adjType = null;
12315                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12316                                    // Not doing bind OOM management, so treat
12317                                    // this guy more like a started service.
12318                                    if (app.hasShownUi && app != mHomeProcess) {
12319                                        // If this process has shown some UI, let it immediately
12320                                        // go to the LRU list because it may be pretty heavy with
12321                                        // UI stuff.  We'll tag it with a label just to help
12322                                        // debug and understand what is going on.
12323                                        if (adj > clientAdj) {
12324                                            adjType = "bound-bg-ui-services";
12325                                        }
12326                                        app.hidden = false;
12327                                        clientAdj = adj;
12328                                    } else {
12329                                        if (now >= (s.lastActivity
12330                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12331                                            // This service has not seen activity within
12332                                            // recent memory, so allow it to drop to the
12333                                            // LRU list if there is no other reason to keep
12334                                            // it around.  We'll also tag it with a label just
12335                                            // to help debug and undertand what is going on.
12336                                            if (adj > clientAdj) {
12337                                                adjType = "bound-bg-services";
12338                                            }
12339                                            clientAdj = adj;
12340                                        }
12341                                    }
12342                                }
12343                                if (adj > clientAdj) {
12344                                    // If this process has recently shown UI, and
12345                                    // the process that is binding to it is less
12346                                    // important than being visible, then we don't
12347                                    // care about the binding as much as we care
12348                                    // about letting this process get into the LRU
12349                                    // list to be killed and restarted if needed for
12350                                    // memory.
12351                                    if (app.hasShownUi && app != mHomeProcess
12352                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12353                                        adjType = "bound-bg-ui-services";
12354                                    } else {
12355                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12356                                                |Context.BIND_IMPORTANT)) != 0) {
12357                                            adj = clientAdj;
12358                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12359                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12360                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12361                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12362                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12363                                            adj = clientAdj;
12364                                        } else {
12365                                            app.pendingUiClean = true;
12366                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12367                                                adj = ProcessList.VISIBLE_APP_ADJ;
12368                                            }
12369                                        }
12370                                        if (!client.hidden) {
12371                                            app.hidden = false;
12372                                        }
12373                                        if (client.keeping) {
12374                                            app.keeping = true;
12375                                        }
12376                                        adjType = "service";
12377                                    }
12378                                }
12379                                if (adjType != null) {
12380                                    app.adjType = adjType;
12381                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12382                                            .REASON_SERVICE_IN_USE;
12383                                    app.adjSource = cr.binding.client;
12384                                    app.adjSourceOom = clientAdj;
12385                                    app.adjTarget = s.name;
12386                                }
12387                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12388                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12389                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12390                                    }
12391                                }
12392                            }
12393                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12394                                ActivityRecord a = cr.activity;
12395                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12396                                        (a.visible || a.state == ActivityState.RESUMED
12397                                         || a.state == ActivityState.PAUSING)) {
12398                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12399                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12400                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12401                                    }
12402                                    app.hidden = false;
12403                                    app.adjType = "service";
12404                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12405                                            .REASON_SERVICE_IN_USE;
12406                                    app.adjSource = a;
12407                                    app.adjSourceOom = adj;
12408                                    app.adjTarget = s.name;
12409                                }
12410                            }
12411                        }
12412                    }
12413                }
12414            }
12415
12416            // Finally, if this process has active services running in it, we
12417            // would like to avoid killing it unless it would prevent the current
12418            // application from running.  By default we put the process in
12419            // with the rest of the background processes; as we scan through
12420            // its services we may bump it up from there.
12421            if (adj > hiddenAdj) {
12422                adj = hiddenAdj;
12423                app.hidden = false;
12424                app.adjType = "bg-services";
12425            }
12426        }
12427
12428        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12429                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12430            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12431            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12432                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12433                ContentProviderRecord cpr = jt.next();
12434                for (int i = cpr.connections.size()-1;
12435                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12436                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12437                        i--) {
12438                    ContentProviderConnection conn = cpr.connections.get(i);
12439                    ProcessRecord client = conn.client;
12440                    if (client == app) {
12441                        // Being our own client is not interesting.
12442                        continue;
12443                    }
12444                    int myHiddenAdj = hiddenAdj;
12445                    if (myHiddenAdj > client.hiddenAdj) {
12446                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12447                            myHiddenAdj = client.hiddenAdj;
12448                        } else {
12449                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12450                        }
12451                    }
12452                    int myEmptyAdj = emptyAdj;
12453                    if (myEmptyAdj > client.emptyAdj) {
12454                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12455                            myEmptyAdj = client.emptyAdj;
12456                        } else {
12457                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12458                        }
12459                    }
12460                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12461                            myEmptyAdj, TOP_APP, true, doingAll);
12462                    if (adj > clientAdj) {
12463                        if (app.hasShownUi && app != mHomeProcess
12464                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12465                            app.adjType = "bg-ui-provider";
12466                        } else {
12467                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12468                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12469                            app.adjType = "provider";
12470                        }
12471                        if (!client.hidden) {
12472                            app.hidden = false;
12473                        }
12474                        if (client.keeping) {
12475                            app.keeping = true;
12476                        }
12477                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12478                                .REASON_PROVIDER_IN_USE;
12479                        app.adjSource = client;
12480                        app.adjSourceOom = clientAdj;
12481                        app.adjTarget = cpr.name;
12482                    }
12483                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12484                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12485                    }
12486                }
12487                // If the provider has external (non-framework) process
12488                // dependencies, ensure that its adjustment is at least
12489                // FOREGROUND_APP_ADJ.
12490                if (cpr.hasExternalProcessHandles()) {
12491                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12492                        adj = ProcessList.FOREGROUND_APP_ADJ;
12493                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12494                        app.hidden = false;
12495                        app.keeping = true;
12496                        app.adjType = "provider";
12497                        app.adjTarget = cpr.name;
12498                    }
12499                }
12500            }
12501        }
12502
12503        if (adj == ProcessList.SERVICE_ADJ) {
12504            if (doingAll) {
12505                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12506                mNewNumServiceProcs++;
12507            }
12508            if (app.serviceb) {
12509                adj = ProcessList.SERVICE_B_ADJ;
12510            }
12511        } else {
12512            app.serviceb = false;
12513        }
12514
12515        app.nonStoppingAdj = adj;
12516
12517        if (hasStoppingActivities) {
12518            // Only upgrade adjustment.
12519            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12520                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12521                app.adjType = "stopping";
12522            }
12523        }
12524
12525        app.curRawAdj = adj;
12526
12527        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12528        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12529        if (adj > app.maxAdj) {
12530            adj = app.maxAdj;
12531            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12532                schedGroup = Process.THREAD_GROUP_DEFAULT;
12533            }
12534        }
12535        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12536            app.keeping = true;
12537        }
12538
12539        if (app.hasAboveClient) {
12540            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12541            // then we need to drop its adjustment to be lower than the service's
12542            // in order to honor the request.  We want to drop it by one adjustment
12543            // level...  but there is special meaning applied to various levels so
12544            // we will skip some of them.
12545            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12546                // System process will not get dropped, ever
12547            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12548                adj = ProcessList.VISIBLE_APP_ADJ;
12549            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12550                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12551            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12552                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
12553            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
12554                adj++;
12555            }
12556        }
12557
12558        int importance = app.memImportance;
12559        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
12560            app.curAdj = adj;
12561            app.curSchedGroup = schedGroup;
12562            if (!interesting) {
12563                // For this reporting, if there is not something explicitly
12564                // interesting in this process then we will push it to the
12565                // background importance.
12566                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12567            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12568                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12569            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
12570                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12571            } else if (adj >= ProcessList.HOME_APP_ADJ) {
12572                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12573            } else if (adj >= ProcessList.SERVICE_ADJ) {
12574                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12575            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12576                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
12577            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
12578                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
12579            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
12580                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
12581            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
12582                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
12583            } else {
12584                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
12585            }
12586        }
12587
12588        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
12589        if (foregroundActivities != app.foregroundActivities) {
12590            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
12591        }
12592        if (changes != 0) {
12593            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
12594            app.memImportance = importance;
12595            app.foregroundActivities = foregroundActivities;
12596            int i = mPendingProcessChanges.size()-1;
12597            ProcessChangeItem item = null;
12598            while (i >= 0) {
12599                item = mPendingProcessChanges.get(i);
12600                if (item.pid == app.pid) {
12601                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
12602                    break;
12603                }
12604                i--;
12605            }
12606            if (i < 0) {
12607                // No existing item in pending changes; need a new one.
12608                final int NA = mAvailProcessChanges.size();
12609                if (NA > 0) {
12610                    item = mAvailProcessChanges.remove(NA-1);
12611                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
12612                } else {
12613                    item = new ProcessChangeItem();
12614                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
12615                }
12616                item.changes = 0;
12617                item.pid = app.pid;
12618                item.uid = app.info.uid;
12619                if (mPendingProcessChanges.size() == 0) {
12620                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
12621                            "*** Enqueueing dispatch processes changed!");
12622                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
12623                }
12624                mPendingProcessChanges.add(item);
12625            }
12626            item.changes |= changes;
12627            item.importance = importance;
12628            item.foregroundActivities = foregroundActivities;
12629            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
12630                    + Integer.toHexString(System.identityHashCode(item))
12631                    + " " + app.toShortString() + ": changes=" + item.changes
12632                    + " importance=" + item.importance
12633                    + " foreground=" + item.foregroundActivities
12634                    + " type=" + app.adjType + " source=" + app.adjSource
12635                    + " target=" + app.adjTarget);
12636        }
12637
12638        return app.curRawAdj;
12639    }
12640
12641    /**
12642     * Ask a given process to GC right now.
12643     */
12644    final void performAppGcLocked(ProcessRecord app) {
12645        try {
12646            app.lastRequestedGc = SystemClock.uptimeMillis();
12647            if (app.thread != null) {
12648                if (app.reportLowMemory) {
12649                    app.reportLowMemory = false;
12650                    app.thread.scheduleLowMemory();
12651                } else {
12652                    app.thread.processInBackground();
12653                }
12654            }
12655        } catch (Exception e) {
12656            // whatever.
12657        }
12658    }
12659
12660    /**
12661     * Returns true if things are idle enough to perform GCs.
12662     */
12663    private final boolean canGcNowLocked() {
12664        boolean processingBroadcasts = false;
12665        for (BroadcastQueue q : mBroadcastQueues) {
12666            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
12667                processingBroadcasts = true;
12668            }
12669        }
12670        return !processingBroadcasts
12671                && (mSleeping || (mMainStack.mResumedActivity != null &&
12672                        mMainStack.mResumedActivity.idle));
12673    }
12674
12675    /**
12676     * Perform GCs on all processes that are waiting for it, but only
12677     * if things are idle.
12678     */
12679    final void performAppGcsLocked() {
12680        final int N = mProcessesToGc.size();
12681        if (N <= 0) {
12682            return;
12683        }
12684        if (canGcNowLocked()) {
12685            while (mProcessesToGc.size() > 0) {
12686                ProcessRecord proc = mProcessesToGc.remove(0);
12687                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
12688                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12689                            <= SystemClock.uptimeMillis()) {
12690                        // To avoid spamming the system, we will GC processes one
12691                        // at a time, waiting a few seconds between each.
12692                        performAppGcLocked(proc);
12693                        scheduleAppGcsLocked();
12694                        return;
12695                    } else {
12696                        // It hasn't been long enough since we last GCed this
12697                        // process...  put it in the list to wait for its time.
12698                        addProcessToGcListLocked(proc);
12699                        break;
12700                    }
12701                }
12702            }
12703
12704            scheduleAppGcsLocked();
12705        }
12706    }
12707
12708    /**
12709     * If all looks good, perform GCs on all processes waiting for them.
12710     */
12711    final void performAppGcsIfAppropriateLocked() {
12712        if (canGcNowLocked()) {
12713            performAppGcsLocked();
12714            return;
12715        }
12716        // Still not idle, wait some more.
12717        scheduleAppGcsLocked();
12718    }
12719
12720    /**
12721     * Schedule the execution of all pending app GCs.
12722     */
12723    final void scheduleAppGcsLocked() {
12724        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
12725
12726        if (mProcessesToGc.size() > 0) {
12727            // Schedule a GC for the time to the next process.
12728            ProcessRecord proc = mProcessesToGc.get(0);
12729            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12730
12731            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
12732            long now = SystemClock.uptimeMillis();
12733            if (when < (now+GC_TIMEOUT)) {
12734                when = now + GC_TIMEOUT;
12735            }
12736            mHandler.sendMessageAtTime(msg, when);
12737        }
12738    }
12739
12740    /**
12741     * Add a process to the array of processes waiting to be GCed.  Keeps the
12742     * list in sorted order by the last GC time.  The process can't already be
12743     * on the list.
12744     */
12745    final void addProcessToGcListLocked(ProcessRecord proc) {
12746        boolean added = false;
12747        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12748            if (mProcessesToGc.get(i).lastRequestedGc <
12749                    proc.lastRequestedGc) {
12750                added = true;
12751                mProcessesToGc.add(i+1, proc);
12752                break;
12753            }
12754        }
12755        if (!added) {
12756            mProcessesToGc.add(0, proc);
12757        }
12758    }
12759
12760    /**
12761     * Set up to ask a process to GC itself.  This will either do it
12762     * immediately, or put it on the list of processes to gc the next
12763     * time things are idle.
12764     */
12765    final void scheduleAppGcLocked(ProcessRecord app) {
12766        long now = SystemClock.uptimeMillis();
12767        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
12768            return;
12769        }
12770        if (!mProcessesToGc.contains(app)) {
12771            addProcessToGcListLocked(app);
12772            scheduleAppGcsLocked();
12773        }
12774    }
12775
12776    final void checkExcessivePowerUsageLocked(boolean doKills) {
12777        updateCpuStatsNow();
12778
12779        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12780        boolean doWakeKills = doKills;
12781        boolean doCpuKills = doKills;
12782        if (mLastPowerCheckRealtime == 0) {
12783            doWakeKills = false;
12784        }
12785        if (mLastPowerCheckUptime == 0) {
12786            doCpuKills = false;
12787        }
12788        if (stats.isScreenOn()) {
12789            doWakeKills = false;
12790        }
12791        final long curRealtime = SystemClock.elapsedRealtime();
12792        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12793        final long curUptime = SystemClock.uptimeMillis();
12794        final long uptimeSince = curUptime - mLastPowerCheckUptime;
12795        mLastPowerCheckRealtime = curRealtime;
12796        mLastPowerCheckUptime = curUptime;
12797        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12798            doWakeKills = false;
12799        }
12800        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12801            doCpuKills = false;
12802        }
12803        int i = mLruProcesses.size();
12804        while (i > 0) {
12805            i--;
12806            ProcessRecord app = mLruProcesses.get(i);
12807            if (!app.keeping) {
12808                long wtime;
12809                synchronized (stats) {
12810                    wtime = stats.getProcessWakeTime(app.info.uid,
12811                            app.pid, curRealtime);
12812                }
12813                long wtimeUsed = wtime - app.lastWakeTime;
12814                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12815                if (DEBUG_POWER) {
12816                    StringBuilder sb = new StringBuilder(128);
12817                    sb.append("Wake for ");
12818                    app.toShortString(sb);
12819                    sb.append(": over ");
12820                    TimeUtils.formatDuration(realtimeSince, sb);
12821                    sb.append(" used ");
12822                    TimeUtils.formatDuration(wtimeUsed, sb);
12823                    sb.append(" (");
12824                    sb.append((wtimeUsed*100)/realtimeSince);
12825                    sb.append("%)");
12826                    Slog.i(TAG, sb.toString());
12827                    sb.setLength(0);
12828                    sb.append("CPU for ");
12829                    app.toShortString(sb);
12830                    sb.append(": over ");
12831                    TimeUtils.formatDuration(uptimeSince, sb);
12832                    sb.append(" used ");
12833                    TimeUtils.formatDuration(cputimeUsed, sb);
12834                    sb.append(" (");
12835                    sb.append((cputimeUsed*100)/uptimeSince);
12836                    sb.append("%)");
12837                    Slog.i(TAG, sb.toString());
12838                }
12839                // If a process has held a wake lock for more
12840                // than 50% of the time during this period,
12841                // that sounds bad.  Kill!
12842                if (doWakeKills && realtimeSince > 0
12843                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
12844                    synchronized (stats) {
12845                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12846                                realtimeSince, wtimeUsed);
12847                    }
12848                    Slog.w(TAG, "Excessive wake lock in " + app.processName
12849                            + " (pid " + app.pid + "): held " + wtimeUsed
12850                            + " during " + realtimeSince);
12851                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12852                            app.processName, app.setAdj, "excessive wake lock");
12853                    Process.killProcessQuiet(app.pid);
12854                } else if (doCpuKills && uptimeSince > 0
12855                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
12856                    synchronized (stats) {
12857                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12858                                uptimeSince, cputimeUsed);
12859                    }
12860                    Slog.w(TAG, "Excessive CPU in " + app.processName
12861                            + " (pid " + app.pid + "): used " + cputimeUsed
12862                            + " during " + uptimeSince);
12863                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12864                            app.processName, app.setAdj, "excessive cpu");
12865                    Process.killProcessQuiet(app.pid);
12866                } else {
12867                    app.lastWakeTime = wtime;
12868                    app.lastCpuTime = app.curCpuTime;
12869                }
12870            }
12871        }
12872    }
12873
12874    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
12875            int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
12876        app.hiddenAdj = hiddenAdj;
12877        app.emptyAdj = emptyAdj;
12878
12879        if (app.thread == null) {
12880            return false;
12881        }
12882
12883        final boolean wasKeeping = app.keeping;
12884
12885        boolean success = true;
12886
12887        computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
12888
12889        if (app.curRawAdj != app.setRawAdj) {
12890            if (wasKeeping && !app.keeping) {
12891                // This app is no longer something we want to keep.  Note
12892                // its current wake lock time to later know to kill it if
12893                // it is not behaving well.
12894                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12895                synchronized (stats) {
12896                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12897                            app.pid, SystemClock.elapsedRealtime());
12898                }
12899                app.lastCpuTime = app.curCpuTime;
12900            }
12901
12902            app.setRawAdj = app.curRawAdj;
12903        }
12904
12905        if (app.curAdj != app.setAdj) {
12906            if (Process.setOomAdj(app.pid, app.curAdj)) {
12907                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
12908                    TAG, "Set " + app.pid + " " + app.processName +
12909                    " adj " + app.curAdj + ": " + app.adjType);
12910                app.setAdj = app.curAdj;
12911            } else {
12912                success = false;
12913                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
12914            }
12915        }
12916        if (app.setSchedGroup != app.curSchedGroup) {
12917            app.setSchedGroup = app.curSchedGroup;
12918            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
12919                    "Setting process group of " + app.processName
12920                    + " to " + app.curSchedGroup);
12921            if (app.waitingToKill != null &&
12922                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
12923                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
12924                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12925                        app.processName, app.setAdj, app.waitingToKill);
12926                app.killedBackground = true;
12927                Process.killProcessQuiet(app.pid);
12928                success = false;
12929            } else {
12930                if (true) {
12931                    long oldId = Binder.clearCallingIdentity();
12932                    try {
12933                        Process.setProcessGroup(app.pid, app.curSchedGroup);
12934                    } catch (Exception e) {
12935                        Slog.w(TAG, "Failed setting process group of " + app.pid
12936                                + " to " + app.curSchedGroup);
12937                        e.printStackTrace();
12938                    } finally {
12939                        Binder.restoreCallingIdentity(oldId);
12940                    }
12941                } else {
12942                    if (app.thread != null) {
12943                        try {
12944                            app.thread.setSchedulingGroup(app.curSchedGroup);
12945                        } catch (RemoteException e) {
12946                        }
12947                    }
12948                }
12949            }
12950        }
12951        return success;
12952    }
12953
12954    private final ActivityRecord resumedAppLocked() {
12955        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
12956        if (resumedActivity == null || resumedActivity.app == null) {
12957            resumedActivity = mMainStack.mPausingActivity;
12958            if (resumedActivity == null || resumedActivity.app == null) {
12959                resumedActivity = mMainStack.topRunningActivityLocked(null);
12960            }
12961        }
12962        return resumedActivity;
12963    }
12964
12965    final boolean updateOomAdjLocked(ProcessRecord app) {
12966        final ActivityRecord TOP_ACT = resumedAppLocked();
12967        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12968        int curAdj = app.curAdj;
12969        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12970            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12971
12972        mAdjSeq++;
12973
12974        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
12975                TOP_APP, false);
12976        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
12977            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
12978        if (nowHidden != wasHidden) {
12979            // Changed to/from hidden state, so apps after it in the LRU
12980            // list may also be changed.
12981            updateOomAdjLocked();
12982        }
12983        return success;
12984    }
12985
12986    final void updateOomAdjLocked() {
12987        final ActivityRecord TOP_ACT = resumedAppLocked();
12988        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12989
12990        if (false) {
12991            RuntimeException e = new RuntimeException();
12992            e.fillInStackTrace();
12993            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
12994        }
12995
12996        mAdjSeq++;
12997        mNewNumServiceProcs = 0;
12998
12999        // Let's determine how many processes we have running vs.
13000        // how many slots we have for background processes; we may want
13001        // to put multiple processes in a slot of there are enough of
13002        // them.
13003        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13004                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13005        int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
13006        if (emptyFactor < 1) emptyFactor = 1;
13007        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13008        if (hiddenFactor < 1) hiddenFactor = 1;
13009        int stepHidden = 0;
13010        int stepEmpty = 0;
13011        final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13012        final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13013        int numHidden = 0;
13014        int numEmpty = 0;
13015        int numTrimming = 0;
13016
13017        mNumNonHiddenProcs = 0;
13018        mNumHiddenProcs = 0;
13019
13020        // First update the OOM adjustment for each of the
13021        // application processes based on their current state.
13022        int i = mLruProcesses.size();
13023        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13024        int nextHiddenAdj = curHiddenAdj+1;
13025        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13026        int nextEmptyAdj = curEmptyAdj+2;
13027        while (i > 0) {
13028            i--;
13029            ProcessRecord app = mLruProcesses.get(i);
13030            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13031            updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
13032            if (!app.killedBackground) {
13033                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13034                    // This process was assigned as a hidden process...  step the
13035                    // hidden level.
13036                    mNumHiddenProcs++;
13037                    if (curHiddenAdj != nextHiddenAdj) {
13038                        stepHidden++;
13039                        if (stepHidden >= hiddenFactor) {
13040                            stepHidden = 0;
13041                            curHiddenAdj = nextHiddenAdj;
13042                            nextHiddenAdj += 2;
13043                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13044                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13045                            }
13046                        }
13047                    }
13048                    numHidden++;
13049                    if (numHidden > hiddenProcessLimit) {
13050                        Slog.i(TAG, "No longer want " + app.processName
13051                                + " (pid " + app.pid + "): hidden #" + numHidden);
13052                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13053                                app.processName, app.setAdj, "too many background");
13054                        app.killedBackground = true;
13055                        Process.killProcessQuiet(app.pid);
13056                    }
13057                } else {
13058                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13059                        // This process was assigned as an empty process...  step the
13060                        // empty level.
13061                        if (curEmptyAdj != nextEmptyAdj) {
13062                            stepEmpty++;
13063                            if (stepEmpty >= emptyFactor) {
13064                                stepEmpty = 0;
13065                                curEmptyAdj = nextEmptyAdj;
13066                                nextEmptyAdj += 2;
13067                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13068                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13069                                }
13070                            }
13071                        }
13072                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13073                        mNumNonHiddenProcs++;
13074                    }
13075                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13076                        numEmpty++;
13077                        if (numEmpty > emptyProcessLimit) {
13078                            Slog.i(TAG, "No longer want " + app.processName
13079                                    + " (pid " + app.pid + "): empty #" + numEmpty);
13080                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13081                                    app.processName, app.setAdj, "too many background");
13082                            app.killedBackground = true;
13083                            Process.killProcessQuiet(app.pid);
13084                        }
13085                    }
13086                }
13087                if (app.isolated && app.services.size() <= 0) {
13088                    // If this is an isolated process, and there are no
13089                    // services running in it, then the process is no longer
13090                    // needed.  We agressively kill these because we can by
13091                    // definition not re-use the same process again, and it is
13092                    // good to avoid having whatever code was running in them
13093                    // left sitting around after no longer needed.
13094                    Slog.i(TAG, "Isolated process " + app.processName
13095                            + " (pid " + app.pid + ") no longer needed");
13096                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13097                            app.processName, app.setAdj, "isolated not needed");
13098                    app.killedBackground = true;
13099                    Process.killProcessQuiet(app.pid);
13100                }
13101                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13102                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13103                        && !app.killedBackground) {
13104                    numTrimming++;
13105                }
13106            }
13107        }
13108
13109        mNumServiceProcs = mNewNumServiceProcs;
13110
13111        // Now determine the memory trimming level of background processes.
13112        // Unfortunately we need to start at the back of the list to do this
13113        // properly.  We only do this if the number of background apps we
13114        // are managing to keep around is less than half the maximum we desire;
13115        // if we are keeping a good number around, we'll let them use whatever
13116        // memory they want.
13117        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13118                && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13119            final int numHiddenAndEmpty = numHidden + numEmpty;
13120            final int N = mLruProcesses.size();
13121            int factor = numTrimming/3;
13122            int minFactor = 2;
13123            if (mHomeProcess != null) minFactor++;
13124            if (mPreviousProcess != null) minFactor++;
13125            if (factor < minFactor) factor = minFactor;
13126            int step = 0;
13127            int fgTrimLevel;
13128            if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13129                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13130            } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13131                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13132            } else {
13133                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13134            }
13135            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13136            for (i=0; i<N; i++) {
13137                ProcessRecord app = mLruProcesses.get(i);
13138                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13139                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13140                        && !app.killedBackground) {
13141                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13142                        try {
13143                            app.thread.scheduleTrimMemory(curLevel);
13144                        } catch (RemoteException e) {
13145                        }
13146                        if (false) {
13147                            // For now we won't do this; our memory trimming seems
13148                            // to be good enough at this point that destroying
13149                            // activities causes more harm than good.
13150                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13151                                    && app != mHomeProcess && app != mPreviousProcess) {
13152                                // Need to do this on its own message because the stack may not
13153                                // be in a consistent state at this point.
13154                                // For these apps we will also finish their activities
13155                                // to help them free memory.
13156                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13157                            }
13158                        }
13159                    }
13160                    app.trimMemoryLevel = curLevel;
13161                    step++;
13162                    if (step >= factor) {
13163                        step = 0;
13164                        switch (curLevel) {
13165                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13166                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13167                                break;
13168                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13169                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13170                                break;
13171                        }
13172                    }
13173                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13174                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13175                            && app.thread != null) {
13176                        try {
13177                            app.thread.scheduleTrimMemory(
13178                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13179                        } catch (RemoteException e) {
13180                        }
13181                    }
13182                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13183                } else {
13184                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13185                            && app.pendingUiClean) {
13186                        // If this application is now in the background and it
13187                        // had done UI, then give it the special trim level to
13188                        // have it free UI resources.
13189                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13190                        if (app.trimMemoryLevel < level && app.thread != null) {
13191                            try {
13192                                app.thread.scheduleTrimMemory(level);
13193                            } catch (RemoteException e) {
13194                            }
13195                        }
13196                        app.pendingUiClean = false;
13197                    }
13198                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13199                        try {
13200                            app.thread.scheduleTrimMemory(fgTrimLevel);
13201                        } catch (RemoteException e) {
13202                        }
13203                    }
13204                    app.trimMemoryLevel = fgTrimLevel;
13205                }
13206            }
13207        } else {
13208            final int N = mLruProcesses.size();
13209            for (i=0; i<N; i++) {
13210                ProcessRecord app = mLruProcesses.get(i);
13211                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13212                        && app.pendingUiClean) {
13213                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13214                            && app.thread != null) {
13215                        try {
13216                            app.thread.scheduleTrimMemory(
13217                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13218                        } catch (RemoteException e) {
13219                        }
13220                    }
13221                    app.pendingUiClean = false;
13222                }
13223                app.trimMemoryLevel = 0;
13224            }
13225        }
13226
13227        if (mAlwaysFinishActivities) {
13228            // Need to do this on its own message because the stack may not
13229            // be in a consistent state at this point.
13230            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13231        }
13232    }
13233
13234    final void trimApplications() {
13235        synchronized (this) {
13236            int i;
13237
13238            // First remove any unused application processes whose package
13239            // has been removed.
13240            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13241                final ProcessRecord app = mRemovedProcesses.get(i);
13242                if (app.activities.size() == 0
13243                        && app.curReceiver == null && app.services.size() == 0) {
13244                    Slog.i(
13245                        TAG, "Exiting empty application process "
13246                        + app.processName + " ("
13247                        + (app.thread != null ? app.thread.asBinder() : null)
13248                        + ")\n");
13249                    if (app.pid > 0 && app.pid != MY_PID) {
13250                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13251                                app.processName, app.setAdj, "empty");
13252                        Process.killProcessQuiet(app.pid);
13253                    } else {
13254                        try {
13255                            app.thread.scheduleExit();
13256                        } catch (Exception e) {
13257                            // Ignore exceptions.
13258                        }
13259                    }
13260                    cleanUpApplicationRecordLocked(app, false, true, -1);
13261                    mRemovedProcesses.remove(i);
13262
13263                    if (app.persistent) {
13264                        if (app.persistent) {
13265                            addAppLocked(app.info, false);
13266                        }
13267                    }
13268                }
13269            }
13270
13271            // Now update the oom adj for all processes.
13272            updateOomAdjLocked();
13273        }
13274    }
13275
13276    /** This method sends the specified signal to each of the persistent apps */
13277    public void signalPersistentProcesses(int sig) throws RemoteException {
13278        if (sig != Process.SIGNAL_USR1) {
13279            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13280        }
13281
13282        synchronized (this) {
13283            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13284                    != PackageManager.PERMISSION_GRANTED) {
13285                throw new SecurityException("Requires permission "
13286                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13287            }
13288
13289            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13290                ProcessRecord r = mLruProcesses.get(i);
13291                if (r.thread != null && r.persistent) {
13292                    Process.sendSignal(r.pid, sig);
13293                }
13294            }
13295        }
13296    }
13297
13298    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13299        if (proc == null || proc == mProfileProc) {
13300            proc = mProfileProc;
13301            path = mProfileFile;
13302            profileType = mProfileType;
13303            clearProfilerLocked();
13304        }
13305        if (proc == null) {
13306            return;
13307        }
13308        try {
13309            proc.thread.profilerControl(false, path, null, profileType);
13310        } catch (RemoteException e) {
13311            throw new IllegalStateException("Process disappeared");
13312        }
13313    }
13314
13315    private void clearProfilerLocked() {
13316        if (mProfileFd != null) {
13317            try {
13318                mProfileFd.close();
13319            } catch (IOException e) {
13320            }
13321        }
13322        mProfileApp = null;
13323        mProfileProc = null;
13324        mProfileFile = null;
13325        mProfileType = 0;
13326        mAutoStopProfiler = false;
13327    }
13328
13329    public boolean profileControl(String process, boolean start,
13330            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13331
13332        try {
13333            synchronized (this) {
13334                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13335                // its own permission.
13336                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13337                        != PackageManager.PERMISSION_GRANTED) {
13338                    throw new SecurityException("Requires permission "
13339                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13340                }
13341
13342                if (start && fd == null) {
13343                    throw new IllegalArgumentException("null fd");
13344                }
13345
13346                ProcessRecord proc = null;
13347                if (process != null) {
13348                    try {
13349                        int pid = Integer.parseInt(process);
13350                        synchronized (mPidsSelfLocked) {
13351                            proc = mPidsSelfLocked.get(pid);
13352                        }
13353                    } catch (NumberFormatException e) {
13354                    }
13355
13356                    if (proc == null) {
13357                        HashMap<String, SparseArray<ProcessRecord>> all
13358                                = mProcessNames.getMap();
13359                        SparseArray<ProcessRecord> procs = all.get(process);
13360                        if (procs != null && procs.size() > 0) {
13361                            proc = procs.valueAt(0);
13362                        }
13363                    }
13364                }
13365
13366                if (start && (proc == null || proc.thread == null)) {
13367                    throw new IllegalArgumentException("Unknown process: " + process);
13368                }
13369
13370                if (start) {
13371                    stopProfilerLocked(null, null, 0);
13372                    setProfileApp(proc.info, proc.processName, path, fd, false);
13373                    mProfileProc = proc;
13374                    mProfileType = profileType;
13375                    try {
13376                        fd = fd.dup();
13377                    } catch (IOException e) {
13378                        fd = null;
13379                    }
13380                    proc.thread.profilerControl(start, path, fd, profileType);
13381                    fd = null;
13382                    mProfileFd = null;
13383                } else {
13384                    stopProfilerLocked(proc, path, profileType);
13385                    if (fd != null) {
13386                        try {
13387                            fd.close();
13388                        } catch (IOException e) {
13389                        }
13390                    }
13391                }
13392
13393                return true;
13394            }
13395        } catch (RemoteException e) {
13396            throw new IllegalStateException("Process disappeared");
13397        } finally {
13398            if (fd != null) {
13399                try {
13400                    fd.close();
13401                } catch (IOException e) {
13402                }
13403            }
13404        }
13405    }
13406
13407    public boolean dumpHeap(String process, boolean managed,
13408            String path, ParcelFileDescriptor fd) throws RemoteException {
13409
13410        try {
13411            synchronized (this) {
13412                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13413                // its own permission (same as profileControl).
13414                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13415                        != PackageManager.PERMISSION_GRANTED) {
13416                    throw new SecurityException("Requires permission "
13417                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13418                }
13419
13420                if (fd == null) {
13421                    throw new IllegalArgumentException("null fd");
13422                }
13423
13424                ProcessRecord proc = null;
13425                try {
13426                    int pid = Integer.parseInt(process);
13427                    synchronized (mPidsSelfLocked) {
13428                        proc = mPidsSelfLocked.get(pid);
13429                    }
13430                } catch (NumberFormatException e) {
13431                }
13432
13433                if (proc == null) {
13434                    HashMap<String, SparseArray<ProcessRecord>> all
13435                            = mProcessNames.getMap();
13436                    SparseArray<ProcessRecord> procs = all.get(process);
13437                    if (procs != null && procs.size() > 0) {
13438                        proc = procs.valueAt(0);
13439                    }
13440                }
13441
13442                if (proc == null || proc.thread == null) {
13443                    throw new IllegalArgumentException("Unknown process: " + process);
13444                }
13445
13446                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13447                if (!isDebuggable) {
13448                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13449                        throw new SecurityException("Process not debuggable: " + proc);
13450                    }
13451                }
13452
13453                proc.thread.dumpHeap(managed, path, fd);
13454                fd = null;
13455                return true;
13456            }
13457        } catch (RemoteException e) {
13458            throw new IllegalStateException("Process disappeared");
13459        } finally {
13460            if (fd != null) {
13461                try {
13462                    fd.close();
13463                } catch (IOException e) {
13464                }
13465            }
13466        }
13467    }
13468
13469    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13470    public void monitor() {
13471        synchronized (this) { }
13472    }
13473
13474    void onCoreSettingsChange(Bundle settings) {
13475        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13476            ProcessRecord processRecord = mLruProcesses.get(i);
13477            try {
13478                if (processRecord.thread != null) {
13479                    processRecord.thread.setCoreSettings(settings);
13480                }
13481            } catch (RemoteException re) {
13482                /* ignore */
13483            }
13484        }
13485    }
13486
13487    // Multi-user methods
13488
13489    public boolean switchUser(int userId) {
13490        final int callingUid = Binder.getCallingUid();
13491        if (callingUid != 0 && callingUid != Process.myUid()) {
13492            Slog.e(TAG, "Trying to switch user from unauthorized app");
13493            return false;
13494        }
13495        if (mCurrentUserId == userId)
13496            return true;
13497
13498        synchronized (this) {
13499            // Check if user is already logged in, otherwise check if user exists first before
13500            // adding to the list of logged in users.
13501            if (mLoggedInUsers.indexOfKey(userId) < 0) {
13502                if (!userExists(userId)) {
13503                    return false;
13504                }
13505                mLoggedInUsers.append(userId, userId);
13506            }
13507
13508            mCurrentUserId = userId;
13509            boolean haveActivities = mMainStack.switchUser(userId);
13510            if (!haveActivities) {
13511                startHomeActivityLocked(userId);
13512            }
13513
13514        }
13515
13516        // Inform of user switch
13517        Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
13518        addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13519        mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_USERS);
13520
13521        return true;
13522    }
13523
13524    @Override
13525    public UserInfo getCurrentUser() throws RemoteException {
13526        final int callingUid = Binder.getCallingUid();
13527        if (callingUid != 0 && callingUid != Process.myUid()) {
13528            Slog.e(TAG, "Trying to get user from unauthorized app");
13529            return null;
13530        }
13531        return getUserManager().getUserInfo(mCurrentUserId);
13532    }
13533
13534    private void onUserRemoved(Intent intent) {
13535        int extraUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
13536        if (extraUserId < 1) return;
13537
13538        // Kill all the processes for the user
13539        ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>();
13540        synchronized (this) {
13541            HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap();
13542            for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) {
13543                SparseArray<ProcessRecord> uids = uidMap.getValue();
13544                for (int i = 0; i < uids.size(); i++) {
13545                    if (UserHandle.getUserId(uids.keyAt(i)) == extraUserId) {
13546                        pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i)));
13547                    }
13548                }
13549            }
13550
13551            for (Pair<String,Integer> pkgAndUid : pkgAndUids) {
13552                forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second,
13553                        false, false, true, true, extraUserId);
13554            }
13555        }
13556    }
13557
13558    private boolean userExists(int userId) {
13559        UserInfo user = getUserManager().getUserInfo(userId);
13560        return user != null;
13561    }
13562
13563    UserManager getUserManager() {
13564        if (mUserManager == null) {
13565            mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
13566        }
13567        return mUserManager;
13568    }
13569
13570    private void checkValidCaller(int uid, int userId) {
13571        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
13572
13573        throw new SecurityException("Caller uid=" + uid
13574                + " is not privileged to communicate with user=" + userId);
13575    }
13576
13577    private int applyUserId(int uid, int userId) {
13578        return UserHandle.getUid(userId, uid);
13579    }
13580
13581    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
13582        if (info == null) return null;
13583        ApplicationInfo newInfo = new ApplicationInfo(info);
13584        newInfo.uid = applyUserId(info.uid, userId);
13585        newInfo.dataDir = USER_DATA_DIR + userId + "/"
13586                + info.packageName;
13587        return newInfo;
13588    }
13589
13590    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
13591        if (aInfo == null
13592                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
13593            return aInfo;
13594        }
13595
13596        ActivityInfo info = new ActivityInfo(aInfo);
13597        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
13598        return info;
13599    }
13600}
13601