ActivityManagerService.java revision e217ee4d7a8223289a1af7363627c69956c46d41
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.IStopUserCallback;
50import android.app.IThumbnailReceiver;
51import android.app.Instrumentation;
52import android.app.Notification;
53import android.app.NotificationManager;
54import android.app.PendingIntent;
55import android.app.backup.IBackupManager;
56import android.content.ActivityNotFoundException;
57import android.content.BroadcastReceiver;
58import android.content.ClipData;
59import android.content.ComponentCallbacks2;
60import android.content.ComponentName;
61import android.content.ContentProvider;
62import android.content.ContentResolver;
63import android.content.Context;
64import android.content.DialogInterface;
65import android.content.IContentProvider;
66import android.content.IIntentReceiver;
67import android.content.IIntentSender;
68import android.content.Intent;
69import android.content.IntentFilter;
70import android.content.IntentSender;
71import android.content.pm.ActivityInfo;
72import android.content.pm.ApplicationInfo;
73import android.content.pm.ConfigurationInfo;
74import android.content.pm.IPackageDataObserver;
75import android.content.pm.IPackageManager;
76import android.content.pm.InstrumentationInfo;
77import android.content.pm.PackageInfo;
78import android.content.pm.PackageManager;
79import android.content.pm.UserInfo;
80import android.content.pm.PackageManager.NameNotFoundException;
81import android.content.pm.PathPermission;
82import android.content.pm.ProviderInfo;
83import android.content.pm.ResolveInfo;
84import android.content.pm.ServiceInfo;
85import android.content.res.CompatibilityInfo;
86import android.content.res.Configuration;
87import android.graphics.Bitmap;
88import android.net.Proxy;
89import android.net.ProxyProperties;
90import android.net.Uri;
91import android.os.Binder;
92import android.os.Build;
93import android.os.Bundle;
94import android.os.Debug;
95import android.os.DropBoxManager;
96import android.os.Environment;
97import android.os.FileObserver;
98import android.os.FileUtils;
99import android.os.Handler;
100import android.os.IBinder;
101import android.os.IPermissionController;
102import android.os.Looper;
103import android.os.Message;
104import android.os.Parcel;
105import android.os.ParcelFileDescriptor;
106import android.os.Process;
107import android.os.RemoteCallbackList;
108import android.os.RemoteException;
109import android.os.SELinux;
110import android.os.ServiceManager;
111import android.os.StrictMode;
112import android.os.SystemClock;
113import android.os.SystemProperties;
114import android.os.UserHandle;
115import android.os.UserManager;
116import android.provider.Settings;
117import android.text.format.Time;
118import android.util.EventLog;
119import android.util.Log;
120import android.util.Pair;
121import android.util.PrintWriterPrinter;
122import android.util.Slog;
123import android.util.SparseArray;
124import android.util.SparseIntArray;
125import android.util.TimeUtils;
126import android.view.Gravity;
127import android.view.LayoutInflater;
128import android.view.View;
129import android.view.WindowManager;
130import android.view.WindowManagerPolicy;
131
132import java.io.BufferedInputStream;
133import java.io.BufferedOutputStream;
134import java.io.BufferedReader;
135import java.io.DataInputStream;
136import java.io.DataOutputStream;
137import java.io.File;
138import java.io.FileDescriptor;
139import java.io.FileInputStream;
140import java.io.FileNotFoundException;
141import java.io.FileOutputStream;
142import java.io.IOException;
143import java.io.InputStreamReader;
144import java.io.PrintWriter;
145import java.io.StringWriter;
146import java.lang.ref.WeakReference;
147import java.util.ArrayList;
148import java.util.Collections;
149import java.util.Comparator;
150import java.util.HashMap;
151import java.util.HashSet;
152import java.util.Iterator;
153import java.util.List;
154import java.util.Locale;
155import java.util.Map;
156import java.util.Map.Entry;
157import java.util.Set;
158import java.util.concurrent.atomic.AtomicBoolean;
159import java.util.concurrent.atomic.AtomicLong;
160
161public final class ActivityManagerService extends ActivityManagerNative
162        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
163    private static final String USER_DATA_DIR = "/data/user/";
164    static final String TAG = "ActivityManager";
165    static final String TAG_MU = "ActivityManagerServiceMU";
166    static final boolean DEBUG = false;
167    static final boolean localLOGV = DEBUG;
168    static final boolean DEBUG_SWITCH = localLOGV || false;
169    static final boolean DEBUG_TASKS = localLOGV || false;
170    static final boolean DEBUG_PAUSE = localLOGV || false;
171    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
172    static final boolean DEBUG_TRANSITION = localLOGV || false;
173    static final boolean DEBUG_BROADCAST = localLOGV || false;
174    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
175    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
176    static final boolean DEBUG_SERVICE = localLOGV || false;
177    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
178    static final boolean DEBUG_VISBILITY = localLOGV || false;
179    static final boolean DEBUG_PROCESSES = localLOGV || false;
180    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
181    static final boolean DEBUG_PROVIDER = localLOGV || false;
182    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
183    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
184    static final boolean DEBUG_RESULTS = localLOGV || false;
185    static final boolean DEBUG_BACKUP = localLOGV || false;
186    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
187    static final boolean DEBUG_POWER = localLOGV || false;
188    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
189    static final boolean DEBUG_MU = localLOGV || false;
190    static final boolean VALIDATE_TOKENS = false;
191    static final boolean SHOW_ACTIVITY_START_TIME = true;
192
193    // Control over CPU and battery monitoring.
194    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
195    static final boolean MONITOR_CPU_USAGE = true;
196    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
197    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
198    static final boolean MONITOR_THREAD_CPU_USAGE = false;
199
200    // The flags that are set for all calls we make to the package manager.
201    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
202
203    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
204
205    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
206
207    // Maximum number of recent tasks that we can remember.
208    static final int MAX_RECENT_TASKS = 20;
209
210    // Amount of time after a call to stopAppSwitches() during which we will
211    // prevent further untrusted switches from happening.
212    static final long APP_SWITCH_DELAY_TIME = 5*1000;
213
214    // How long we wait for a launched process to attach to the activity manager
215    // before we decide it's never going to come up for real.
216    static final int PROC_START_TIMEOUT = 10*1000;
217
218    // How long we wait for a launched process to attach to the activity manager
219    // before we decide it's never going to come up for real, when the process was
220    // started with a wrapper for instrumentation (such as Valgrind) because it
221    // could take much longer than usual.
222    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
223
224    // How long to wait after going idle before forcing apps to GC.
225    static final int GC_TIMEOUT = 5*1000;
226
227    // The minimum amount of time between successive GC requests for a process.
228    static final int GC_MIN_INTERVAL = 60*1000;
229
230    // The rate at which we check for apps using excessive power -- 15 mins.
231    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
232
233    // The minimum sample duration we will allow before deciding we have
234    // enough data on wake locks to start killing things.
235    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
236
237    // The minimum sample duration we will allow before deciding we have
238    // enough data on CPU usage to start killing things.
239    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
240
241    // How long we allow a receiver to run before giving up on it.
242    static final int BROADCAST_FG_TIMEOUT = 10*1000;
243    static final int BROADCAST_BG_TIMEOUT = 60*1000;
244
245    // How long we wait until we timeout on key dispatching.
246    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
247
248    // How long we wait until we timeout on key dispatching during instrumentation.
249    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
250
251    static final int MY_PID = Process.myPid();
252
253    static final String[] EMPTY_STRING_ARRAY = new String[0];
254
255    public ActivityStack mMainStack;
256
257    private final boolean mHeadless;
258
259    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
260    // default actuion automatically.  Important for devices without direct input
261    // devices.
262    private boolean mShowDialogs = true;
263
264    /**
265     * Description of a request to start a new activity, which has been held
266     * due to app switches being disabled.
267     */
268    static class PendingActivityLaunch {
269        ActivityRecord r;
270        ActivityRecord sourceRecord;
271        int startFlags;
272    }
273
274    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
275            = new ArrayList<PendingActivityLaunch>();
276
277
278    BroadcastQueue mFgBroadcastQueue;
279    BroadcastQueue mBgBroadcastQueue;
280    // Convenient for easy iteration over the queues. Foreground is first
281    // so that dispatch of foreground broadcasts gets precedence.
282    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
283
284    BroadcastQueue broadcastQueueForIntent(Intent intent) {
285        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
286        if (DEBUG_BACKGROUND_BROADCAST) {
287            Slog.i(TAG, "Broadcast intent " + intent + " on "
288                    + (isFg ? "foreground" : "background")
289                    + " queue");
290        }
291        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
292    }
293
294    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
295        for (BroadcastQueue queue : mBroadcastQueues) {
296            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
297            if (r != null) {
298                return r;
299            }
300        }
301        return null;
302    }
303
304    /**
305     * Activity we have told the window manager to have key focus.
306     */
307    ActivityRecord mFocusedActivity = null;
308    /**
309     * List of intents that were used to start the most recent tasks.
310     */
311    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
312
313    /**
314     * Process management.
315     */
316    final ProcessList mProcessList = new ProcessList();
317
318    /**
319     * All of the applications we currently have running organized by name.
320     * The keys are strings of the application package name (as
321     * returned by the package manager), and the keys are ApplicationRecord
322     * objects.
323     */
324    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
325
326    /**
327     * The currently running isolated processes.
328     */
329    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
330
331    /**
332     * Counter for assigning isolated process uids, to avoid frequently reusing the
333     * same ones.
334     */
335    int mNextIsolatedProcessUid = 0;
336
337    /**
338     * The currently running heavy-weight process, if any.
339     */
340    ProcessRecord mHeavyWeightProcess = null;
341
342    /**
343     * The last time that various processes have crashed.
344     */
345    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
346
347    /**
348     * Set of applications that we consider to be bad, and will reject
349     * incoming broadcasts from (which the user has no control over).
350     * Processes are added to this set when they have crashed twice within
351     * a minimum amount of time; they are removed from it when they are
352     * later restarted (hopefully due to some user action).  The value is the
353     * time it was added to the list.
354     */
355    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
356
357    /**
358     * All of the processes we currently have running organized by pid.
359     * The keys are the pid running the application.
360     *
361     * <p>NOTE: This object is protected by its own lock, NOT the global
362     * activity manager lock!
363     */
364    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
365
366    /**
367     * All of the processes that have been forced to be foreground.  The key
368     * is the pid of the caller who requested it (we hold a death
369     * link on it).
370     */
371    abstract class ForegroundToken implements IBinder.DeathRecipient {
372        int pid;
373        IBinder token;
374    }
375    final SparseArray<ForegroundToken> mForegroundProcesses
376            = new SparseArray<ForegroundToken>();
377
378    /**
379     * List of records for processes that someone had tried to start before the
380     * system was ready.  We don't start them at that point, but ensure they
381     * are started by the time booting is complete.
382     */
383    final ArrayList<ProcessRecord> mProcessesOnHold
384            = new ArrayList<ProcessRecord>();
385
386    /**
387     * List of persistent applications that are in the process
388     * of being started.
389     */
390    final ArrayList<ProcessRecord> mPersistentStartingProcesses
391            = new ArrayList<ProcessRecord>();
392
393    /**
394     * Processes that are being forcibly torn down.
395     */
396    final ArrayList<ProcessRecord> mRemovedProcesses
397            = new ArrayList<ProcessRecord>();
398
399    /**
400     * List of running applications, sorted by recent usage.
401     * The first entry in the list is the least recently used.
402     * It contains ApplicationRecord objects.  This list does NOT include
403     * any persistent application records (since we never want to exit them).
404     */
405    final ArrayList<ProcessRecord> mLruProcesses
406            = new ArrayList<ProcessRecord>();
407
408    /**
409     * List of processes that should gc as soon as things are idle.
410     */
411    final ArrayList<ProcessRecord> mProcessesToGc
412            = new ArrayList<ProcessRecord>();
413
414    /**
415     * This is the process holding what we currently consider to be
416     * the "home" activity.
417     */
418    ProcessRecord mHomeProcess;
419
420    /**
421     * This is the process holding the activity the user last visited that
422     * is in a different process from the one they are currently in.
423     */
424    ProcessRecord mPreviousProcess;
425
426    /**
427     * The time at which the previous process was last visible.
428     */
429    long mPreviousProcessVisibleTime;
430
431    /**
432     * Which uses have been started, so are allowed to run code.
433     */
434    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
435
436    /**
437     * Packages that the user has asked to have run in screen size
438     * compatibility mode instead of filling the screen.
439     */
440    final CompatModePackages mCompatModePackages;
441
442    /**
443     * Set of PendingResultRecord objects that are currently active.
444     */
445    final HashSet mPendingResultRecords = new HashSet();
446
447    /**
448     * Set of IntentSenderRecord objects that are currently active.
449     */
450    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
451            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
452
453    /**
454     * Fingerprints (hashCode()) of stack traces that we've
455     * already logged DropBox entries for.  Guarded by itself.  If
456     * something (rogue user app) forces this over
457     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
458     */
459    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
460    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
461
462    /**
463     * Strict Mode background batched logging state.
464     *
465     * The string buffer is guarded by itself, and its lock is also
466     * used to determine if another batched write is already
467     * in-flight.
468     */
469    private final StringBuilder mStrictModeBuffer = new StringBuilder();
470
471    /**
472     * Keeps track of all IIntentReceivers that have been registered for
473     * broadcasts.  Hash keys are the receiver IBinder, hash value is
474     * a ReceiverList.
475     */
476    final HashMap mRegisteredReceivers = new HashMap();
477
478    /**
479     * Resolver for broadcast intents to registered receivers.
480     * Holds BroadcastFilter (subclass of IntentFilter).
481     */
482    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
483            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
484        @Override
485        protected boolean allowFilterResult(
486                BroadcastFilter filter, List<BroadcastFilter> dest) {
487            IBinder target = filter.receiverList.receiver.asBinder();
488            for (int i=dest.size()-1; i>=0; i--) {
489                if (dest.get(i).receiverList.receiver.asBinder() == target) {
490                    return false;
491                }
492            }
493            return true;
494        }
495
496        @Override
497        protected BroadcastFilter[] newArray(int size) {
498            return new BroadcastFilter[size];
499        }
500
501        @Override
502        protected String packageForFilter(BroadcastFilter filter) {
503            return filter.packageName;
504        }
505    };
506
507    /**
508     * State of all active sticky broadcasts.  Keys are the action of the
509     * sticky Intent, values are an ArrayList of all broadcasted intents with
510     * that action (which should usually be one).
511     */
512    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
513            new HashMap<String, ArrayList<Intent>>();
514
515    final ActiveServices mServices;
516
517    /**
518     * Backup/restore process management
519     */
520    String mBackupAppName = null;
521    BackupRecord mBackupTarget = null;
522
523    /**
524     * List of PendingThumbnailsRecord objects of clients who are still
525     * waiting to receive all of the thumbnails for a task.
526     */
527    final ArrayList mPendingThumbnails = new ArrayList();
528
529    /**
530     * List of HistoryRecord objects that have been finished and must
531     * still report back to a pending thumbnail receiver.
532     */
533    final ArrayList mCancelledThumbnails = new ArrayList();
534
535    final ProviderMap mProviderMap = new ProviderMap();
536
537    /**
538     * List of content providers who have clients waiting for them.  The
539     * application is currently being launched and the provider will be
540     * removed from this list once it is published.
541     */
542    final ArrayList<ContentProviderRecord> mLaunchingProviders
543            = new ArrayList<ContentProviderRecord>();
544
545    /**
546     * Global set of specific Uri permissions that have been granted.
547     */
548    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
549            = new SparseArray<HashMap<Uri, UriPermission>>();
550
551    CoreSettingsObserver mCoreSettingsObserver;
552
553    /**
554     * Thread-local storage used to carry caller permissions over through
555     * indirect content-provider access.
556     * @see #ActivityManagerService.openContentUri()
557     */
558    private class Identity {
559        public int pid;
560        public int uid;
561
562        Identity(int _pid, int _uid) {
563            pid = _pid;
564            uid = _uid;
565        }
566    }
567
568    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
569
570    /**
571     * All information we have collected about the runtime performance of
572     * any user id that can impact battery performance.
573     */
574    final BatteryStatsService mBatteryStatsService;
575
576    /**
577     * information about component usage
578     */
579    final UsageStatsService mUsageStatsService;
580
581    /**
582     * Current configuration information.  HistoryRecord objects are given
583     * a reference to this object to indicate which configuration they are
584     * currently running in, so this object must be kept immutable.
585     */
586    Configuration mConfiguration = new Configuration();
587
588    /**
589     * Current sequencing integer of the configuration, for skipping old
590     * configurations.
591     */
592    int mConfigurationSeq = 0;
593
594    /**
595     * Hardware-reported OpenGLES version.
596     */
597    final int GL_ES_VERSION;
598
599    /**
600     * List of initialization arguments to pass to all processes when binding applications to them.
601     * For example, references to the commonly used services.
602     */
603    HashMap<String, IBinder> mAppBindArgs;
604
605    /**
606     * Temporary to avoid allocations.  Protected by main lock.
607     */
608    final StringBuilder mStringBuilder = new StringBuilder(256);
609
610    /**
611     * Used to control how we initialize the service.
612     */
613    boolean mStartRunning = false;
614    ComponentName mTopComponent;
615    String mTopAction;
616    String mTopData;
617    boolean mProcessesReady = false;
618    boolean mSystemReady = false;
619    boolean mBooting = false;
620    boolean mWaitingUpdate = false;
621    boolean mDidUpdate = false;
622    boolean mOnBattery = false;
623    boolean mLaunchWarningShown = false;
624
625    Context mContext;
626
627    int mFactoryTest;
628
629    boolean mCheckedForSetup;
630
631    /**
632     * The time at which we will allow normal application switches again,
633     * after a call to {@link #stopAppSwitches()}.
634     */
635    long mAppSwitchesAllowedTime;
636
637    /**
638     * This is set to true after the first switch after mAppSwitchesAllowedTime
639     * is set; any switches after that will clear the time.
640     */
641    boolean mDidAppSwitch;
642
643    /**
644     * Last time (in realtime) at which we checked for power usage.
645     */
646    long mLastPowerCheckRealtime;
647
648    /**
649     * Last time (in uptime) at which we checked for power usage.
650     */
651    long mLastPowerCheckUptime;
652
653    /**
654     * Set while we are wanting to sleep, to prevent any
655     * activities from being started/resumed.
656     */
657    boolean mSleeping = false;
658
659    /**
660     * State of external calls telling us if the device is asleep.
661     */
662    boolean mWentToSleep = false;
663
664    /**
665     * State of external call telling us if the lock screen is shown.
666     */
667    boolean mLockScreenShown = false;
668
669    /**
670     * Set if we are shutting down the system, similar to sleeping.
671     */
672    boolean mShuttingDown = false;
673
674    /**
675     * Task identifier that activities are currently being started
676     * in.  Incremented each time a new task is created.
677     * todo: Replace this with a TokenSpace class that generates non-repeating
678     * integers that won't wrap.
679     */
680    int mCurTask = 1;
681
682    /**
683     * Current sequence id for oom_adj computation traversal.
684     */
685    int mAdjSeq = 0;
686
687    /**
688     * Current sequence id for process LRU updating.
689     */
690    int mLruSeq = 0;
691
692    /**
693     * Keep track of the non-hidden/empty process we last found, to help
694     * determine how to distribute hidden/empty processes next time.
695     */
696    int mNumNonHiddenProcs = 0;
697
698    /**
699     * Keep track of the number of hidden procs, to balance oom adj
700     * distribution between those and empty procs.
701     */
702    int mNumHiddenProcs = 0;
703
704    /**
705     * Keep track of the number of service processes we last found, to
706     * determine on the next iteration which should be B services.
707     */
708    int mNumServiceProcs = 0;
709    int mNewNumServiceProcs = 0;
710
711    /**
712     * System monitoring: number of processes that died since the last
713     * N procs were started.
714     */
715    int[] mProcDeaths = new int[20];
716
717    /**
718     * This is set if we had to do a delayed dexopt of an app before launching
719     * it, to increasing the ANR timeouts in that case.
720     */
721    boolean mDidDexOpt;
722
723    String mDebugApp = null;
724    boolean mWaitForDebugger = false;
725    boolean mDebugTransient = false;
726    String mOrigDebugApp = null;
727    boolean mOrigWaitForDebugger = false;
728    boolean mAlwaysFinishActivities = false;
729    IActivityController mController = null;
730    String mProfileApp = null;
731    ProcessRecord mProfileProc = null;
732    String mProfileFile;
733    ParcelFileDescriptor mProfileFd;
734    int mProfileType = 0;
735    boolean mAutoStopProfiler = false;
736    String mOpenGlTraceApp = null;
737
738    static class ProcessChangeItem {
739        static final int CHANGE_ACTIVITIES = 1<<0;
740        static final int CHANGE_IMPORTANCE= 1<<1;
741        int changes;
742        int uid;
743        int pid;
744        int importance;
745        boolean foregroundActivities;
746    }
747
748    final RemoteCallbackList<IProcessObserver> mProcessObservers
749            = new RemoteCallbackList<IProcessObserver>();
750    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
751
752    final ArrayList<ProcessChangeItem> mPendingProcessChanges
753            = new ArrayList<ProcessChangeItem>();
754    final ArrayList<ProcessChangeItem> mAvailProcessChanges
755            = new ArrayList<ProcessChangeItem>();
756
757    /**
758     * Callback of last caller to {@link #requestPss}.
759     */
760    Runnable mRequestPssCallback;
761
762    /**
763     * Remaining processes for which we are waiting results from the last
764     * call to {@link #requestPss}.
765     */
766    final ArrayList<ProcessRecord> mRequestPssList
767            = new ArrayList<ProcessRecord>();
768
769    /**
770     * Runtime statistics collection thread.  This object's lock is used to
771     * protect all related state.
772     */
773    final Thread mProcessStatsThread;
774
775    /**
776     * Used to collect process stats when showing not responding dialog.
777     * Protected by mProcessStatsThread.
778     */
779    final ProcessStats mProcessStats = new ProcessStats(
780            MONITOR_THREAD_CPU_USAGE);
781    final AtomicLong mLastCpuTime = new AtomicLong(0);
782    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
783
784    long mLastWriteTime = 0;
785
786    /**
787     * Set to true after the system has finished booting.
788     */
789    boolean mBooted = false;
790
791    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
792    int mProcessLimitOverride = -1;
793
794    WindowManagerService mWindowManager;
795
796    static ActivityManagerService mSelf;
797    static ActivityThread mSystemThread;
798
799    private int mCurrentUserId;
800    private UserManager mUserManager;
801
802    private final class AppDeathRecipient implements IBinder.DeathRecipient {
803        final ProcessRecord mApp;
804        final int mPid;
805        final IApplicationThread mAppThread;
806
807        AppDeathRecipient(ProcessRecord app, int pid,
808                IApplicationThread thread) {
809            if (localLOGV) Slog.v(
810                TAG, "New death recipient " + this
811                + " for thread " + thread.asBinder());
812            mApp = app;
813            mPid = pid;
814            mAppThread = thread;
815        }
816
817        public void binderDied() {
818            if (localLOGV) Slog.v(
819                TAG, "Death received in " + this
820                + " for thread " + mAppThread.asBinder());
821            synchronized(ActivityManagerService.this) {
822                appDiedLocked(mApp, mPid, mAppThread);
823            }
824        }
825    }
826
827    static final int SHOW_ERROR_MSG = 1;
828    static final int SHOW_NOT_RESPONDING_MSG = 2;
829    static final int SHOW_FACTORY_ERROR_MSG = 3;
830    static final int UPDATE_CONFIGURATION_MSG = 4;
831    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
832    static final int WAIT_FOR_DEBUGGER_MSG = 6;
833    static final int SERVICE_TIMEOUT_MSG = 12;
834    static final int UPDATE_TIME_ZONE = 13;
835    static final int SHOW_UID_ERROR_MSG = 14;
836    static final int IM_FEELING_LUCKY_MSG = 15;
837    static final int PROC_START_TIMEOUT_MSG = 20;
838    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
839    static final int KILL_APPLICATION_MSG = 22;
840    static final int FINALIZE_PENDING_INTENT_MSG = 23;
841    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
842    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
843    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
844    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
845    static final int CLEAR_DNS_CACHE = 28;
846    static final int UPDATE_HTTP_PROXY = 29;
847    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
848    static final int DISPATCH_PROCESSES_CHANGED = 31;
849    static final int DISPATCH_PROCESS_DIED = 32;
850    static final int REPORT_MEM_USAGE = 33;
851
852    static final int FIRST_ACTIVITY_STACK_MSG = 100;
853    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
854    static final int FIRST_COMPAT_MODE_MSG = 300;
855
856    AlertDialog mUidAlert;
857    CompatModeDialog mCompatModeDialog;
858    long mLastMemUsageReportTime = 0;
859
860    final Handler mHandler = new Handler() {
861        //public Handler() {
862        //    if (localLOGV) Slog.v(TAG, "Handler started!");
863        //}
864
865        public void handleMessage(Message msg) {
866            switch (msg.what) {
867            case SHOW_ERROR_MSG: {
868                HashMap data = (HashMap) msg.obj;
869                synchronized (ActivityManagerService.this) {
870                    ProcessRecord proc = (ProcessRecord)data.get("app");
871                    if (proc != null && proc.crashDialog != null) {
872                        Slog.e(TAG, "App already has crash dialog: " + proc);
873                        return;
874                    }
875                    AppErrorResult res = (AppErrorResult) data.get("result");
876                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
877                        Dialog d = new AppErrorDialog(mContext, res, proc);
878                        d.show();
879                        proc.crashDialog = d;
880                    } else {
881                        // The device is asleep, so just pretend that the user
882                        // saw a crash dialog and hit "force quit".
883                        res.set(0);
884                    }
885                }
886
887                ensureBootCompleted();
888            } break;
889            case SHOW_NOT_RESPONDING_MSG: {
890                synchronized (ActivityManagerService.this) {
891                    HashMap data = (HashMap) msg.obj;
892                    ProcessRecord proc = (ProcessRecord)data.get("app");
893                    if (proc != null && proc.anrDialog != null) {
894                        Slog.e(TAG, "App already has anr dialog: " + proc);
895                        return;
896                    }
897
898                    Intent intent = new Intent("android.intent.action.ANR");
899                    if (!mProcessesReady) {
900                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
901                                | Intent.FLAG_RECEIVER_FOREGROUND);
902                    }
903                    broadcastIntentLocked(null, null, intent,
904                            null, null, 0, null, null, null,
905                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
906
907                    if (mShowDialogs) {
908                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
909                                mContext, proc, (ActivityRecord)data.get("activity"));
910                        d.show();
911                        proc.anrDialog = d;
912                    } else {
913                        // Just kill the app if there is no dialog to be shown.
914                        killAppAtUsersRequest(proc, null);
915                    }
916                }
917
918                ensureBootCompleted();
919            } break;
920            case SHOW_STRICT_MODE_VIOLATION_MSG: {
921                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
922                synchronized (ActivityManagerService.this) {
923                    ProcessRecord proc = (ProcessRecord) data.get("app");
924                    if (proc == null) {
925                        Slog.e(TAG, "App not found when showing strict mode dialog.");
926                        break;
927                    }
928                    if (proc.crashDialog != null) {
929                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
930                        return;
931                    }
932                    AppErrorResult res = (AppErrorResult) data.get("result");
933                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
934                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
935                        d.show();
936                        proc.crashDialog = d;
937                    } else {
938                        // The device is asleep, so just pretend that the user
939                        // saw a crash dialog and hit "force quit".
940                        res.set(0);
941                    }
942                }
943                ensureBootCompleted();
944            } break;
945            case SHOW_FACTORY_ERROR_MSG: {
946                Dialog d = new FactoryErrorDialog(
947                    mContext, msg.getData().getCharSequence("msg"));
948                d.show();
949                ensureBootCompleted();
950            } break;
951            case UPDATE_CONFIGURATION_MSG: {
952                final ContentResolver resolver = mContext.getContentResolver();
953                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
954            } break;
955            case GC_BACKGROUND_PROCESSES_MSG: {
956                synchronized (ActivityManagerService.this) {
957                    performAppGcsIfAppropriateLocked();
958                }
959            } break;
960            case WAIT_FOR_DEBUGGER_MSG: {
961                synchronized (ActivityManagerService.this) {
962                    ProcessRecord app = (ProcessRecord)msg.obj;
963                    if (msg.arg1 != 0) {
964                        if (!app.waitedForDebugger) {
965                            Dialog d = new AppWaitingForDebuggerDialog(
966                                    ActivityManagerService.this,
967                                    mContext, app);
968                            app.waitDialog = d;
969                            app.waitedForDebugger = true;
970                            d.show();
971                        }
972                    } else {
973                        if (app.waitDialog != null) {
974                            app.waitDialog.dismiss();
975                            app.waitDialog = null;
976                        }
977                    }
978                }
979            } break;
980            case SERVICE_TIMEOUT_MSG: {
981                if (mDidDexOpt) {
982                    mDidDexOpt = false;
983                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
984                    nmsg.obj = msg.obj;
985                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
986                    return;
987                }
988                mServices.serviceTimeout((ProcessRecord)msg.obj);
989            } break;
990            case UPDATE_TIME_ZONE: {
991                synchronized (ActivityManagerService.this) {
992                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
993                        ProcessRecord r = mLruProcesses.get(i);
994                        if (r.thread != null) {
995                            try {
996                                r.thread.updateTimeZone();
997                            } catch (RemoteException ex) {
998                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
999                            }
1000                        }
1001                    }
1002                }
1003            } break;
1004            case CLEAR_DNS_CACHE: {
1005                synchronized (ActivityManagerService.this) {
1006                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1007                        ProcessRecord r = mLruProcesses.get(i);
1008                        if (r.thread != null) {
1009                            try {
1010                                r.thread.clearDnsCache();
1011                            } catch (RemoteException ex) {
1012                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1013                            }
1014                        }
1015                    }
1016                }
1017            } break;
1018            case UPDATE_HTTP_PROXY: {
1019                ProxyProperties proxy = (ProxyProperties)msg.obj;
1020                String host = "";
1021                String port = "";
1022                String exclList = "";
1023                if (proxy != null) {
1024                    host = proxy.getHost();
1025                    port = Integer.toString(proxy.getPort());
1026                    exclList = proxy.getExclusionList();
1027                }
1028                synchronized (ActivityManagerService.this) {
1029                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1030                        ProcessRecord r = mLruProcesses.get(i);
1031                        if (r.thread != null) {
1032                            try {
1033                                r.thread.setHttpProxy(host, port, exclList);
1034                            } catch (RemoteException ex) {
1035                                Slog.w(TAG, "Failed to update http proxy for: " +
1036                                        r.info.processName);
1037                            }
1038                        }
1039                    }
1040                }
1041            } break;
1042            case SHOW_UID_ERROR_MSG: {
1043                String title = "System UIDs Inconsistent";
1044                String text = "UIDs on the system are inconsistent, you need to wipe your"
1045                        + " data partition or your device will be unstable.";
1046                Log.e(TAG, title + ": " + text);
1047                if (mShowDialogs) {
1048                    // XXX This is a temporary dialog, no need to localize.
1049                    AlertDialog d = new BaseErrorDialog(mContext);
1050                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1051                    d.setCancelable(false);
1052                    d.setTitle(title);
1053                    d.setMessage(text);
1054                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1055                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1056                    mUidAlert = d;
1057                    d.show();
1058                }
1059            } break;
1060            case IM_FEELING_LUCKY_MSG: {
1061                if (mUidAlert != null) {
1062                    mUidAlert.dismiss();
1063                    mUidAlert = null;
1064                }
1065            } break;
1066            case PROC_START_TIMEOUT_MSG: {
1067                if (mDidDexOpt) {
1068                    mDidDexOpt = false;
1069                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1070                    nmsg.obj = msg.obj;
1071                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1072                    return;
1073                }
1074                ProcessRecord app = (ProcessRecord)msg.obj;
1075                synchronized (ActivityManagerService.this) {
1076                    processStartTimedOutLocked(app);
1077                }
1078            } break;
1079            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1080                synchronized (ActivityManagerService.this) {
1081                    doPendingActivityLaunchesLocked(true);
1082                }
1083            } break;
1084            case KILL_APPLICATION_MSG: {
1085                synchronized (ActivityManagerService.this) {
1086                    int uid = msg.arg1;
1087                    boolean restart = (msg.arg2 == 1);
1088                    String pkg = (String) msg.obj;
1089                    forceStopPackageLocked(pkg, uid, restart, false, true, false,
1090                            UserHandle.getUserId(uid));
1091                }
1092            } break;
1093            case FINALIZE_PENDING_INTENT_MSG: {
1094                ((PendingIntentRecord)msg.obj).completeFinalize();
1095            } break;
1096            case POST_HEAVY_NOTIFICATION_MSG: {
1097                INotificationManager inm = NotificationManager.getService();
1098                if (inm == null) {
1099                    return;
1100                }
1101
1102                ActivityRecord root = (ActivityRecord)msg.obj;
1103                ProcessRecord process = root.app;
1104                if (process == null) {
1105                    return;
1106                }
1107
1108                try {
1109                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1110                    String text = mContext.getString(R.string.heavy_weight_notification,
1111                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1112                    Notification notification = new Notification();
1113                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1114                    notification.when = 0;
1115                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1116                    notification.tickerText = text;
1117                    notification.defaults = 0; // please be quiet
1118                    notification.sound = null;
1119                    notification.vibrate = null;
1120                    notification.setLatestEventInfo(context, text,
1121                            mContext.getText(R.string.heavy_weight_notification_detail),
1122                            PendingIntent.getActivity(mContext, 0, root.intent,
1123                                    PendingIntent.FLAG_CANCEL_CURRENT));
1124
1125                    try {
1126                        int[] outId = new int[1];
1127                        inm.enqueueNotification("android", R.string.heavy_weight_notification,
1128                                notification, outId);
1129                    } catch (RuntimeException e) {
1130                        Slog.w(ActivityManagerService.TAG,
1131                                "Error showing notification for heavy-weight app", e);
1132                    } catch (RemoteException e) {
1133                    }
1134                } catch (NameNotFoundException e) {
1135                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1136                }
1137            } break;
1138            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1139                INotificationManager inm = NotificationManager.getService();
1140                if (inm == null) {
1141                    return;
1142                }
1143                try {
1144                    inm.cancelNotification("android",
1145                            R.string.heavy_weight_notification);
1146                } catch (RuntimeException e) {
1147                    Slog.w(ActivityManagerService.TAG,
1148                            "Error canceling notification for service", e);
1149                } catch (RemoteException e) {
1150                }
1151            } break;
1152            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1153                synchronized (ActivityManagerService.this) {
1154                    checkExcessivePowerUsageLocked(true);
1155                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1156                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1157                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1158                }
1159            } break;
1160            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1161                synchronized (ActivityManagerService.this) {
1162                    ActivityRecord ar = (ActivityRecord)msg.obj;
1163                    if (mCompatModeDialog != null) {
1164                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1165                                ar.info.applicationInfo.packageName)) {
1166                            return;
1167                        }
1168                        mCompatModeDialog.dismiss();
1169                        mCompatModeDialog = null;
1170                    }
1171                    if (ar != null && false) {
1172                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1173                                ar.packageName)) {
1174                            int mode = mCompatModePackages.computeCompatModeLocked(
1175                                    ar.info.applicationInfo);
1176                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1177                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1178                                mCompatModeDialog = new CompatModeDialog(
1179                                        ActivityManagerService.this, mContext,
1180                                        ar.info.applicationInfo);
1181                                mCompatModeDialog.show();
1182                            }
1183                        }
1184                    }
1185                }
1186                break;
1187            }
1188            case DISPATCH_PROCESSES_CHANGED: {
1189                dispatchProcessesChanged();
1190                break;
1191            }
1192            case DISPATCH_PROCESS_DIED: {
1193                final int pid = msg.arg1;
1194                final int uid = msg.arg2;
1195                dispatchProcessDied(pid, uid);
1196                break;
1197            }
1198            case REPORT_MEM_USAGE: {
1199                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1200                if (!isDebuggable) {
1201                    return;
1202                }
1203                synchronized (ActivityManagerService.this) {
1204                    long now = SystemClock.uptimeMillis();
1205                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1206                        // Don't report more than every 5 minutes to somewhat
1207                        // avoid spamming.
1208                        return;
1209                    }
1210                    mLastMemUsageReportTime = now;
1211                }
1212                Thread thread = new Thread() {
1213                    @Override public void run() {
1214                        StringBuilder dropBuilder = new StringBuilder(1024);
1215                        StringBuilder logBuilder = new StringBuilder(1024);
1216                        StringWriter oomSw = new StringWriter();
1217                        PrintWriter oomPw = new PrintWriter(oomSw);
1218                        StringWriter catSw = new StringWriter();
1219                        PrintWriter catPw = new PrintWriter(catSw);
1220                        String[] emptyArgs = new String[] { };
1221                        StringBuilder tag = new StringBuilder(128);
1222                        StringBuilder stack = new StringBuilder(128);
1223                        tag.append("Low on memory -- ");
1224                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1225                                tag, stack);
1226                        dropBuilder.append(stack);
1227                        dropBuilder.append('\n');
1228                        dropBuilder.append('\n');
1229                        String oomString = oomSw.toString();
1230                        dropBuilder.append(oomString);
1231                        dropBuilder.append('\n');
1232                        logBuilder.append(oomString);
1233                        try {
1234                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1235                                    "procrank", });
1236                            final InputStreamReader converter = new InputStreamReader(
1237                                    proc.getInputStream());
1238                            BufferedReader in = new BufferedReader(converter);
1239                            String line;
1240                            while (true) {
1241                                line = in.readLine();
1242                                if (line == null) {
1243                                    break;
1244                                }
1245                                if (line.length() > 0) {
1246                                    logBuilder.append(line);
1247                                    logBuilder.append('\n');
1248                                }
1249                                dropBuilder.append(line);
1250                                dropBuilder.append('\n');
1251                            }
1252                            converter.close();
1253                        } catch (IOException e) {
1254                        }
1255                        synchronized (ActivityManagerService.this) {
1256                            catPw.println();
1257                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1258                            catPw.println();
1259                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1260                                    false, false, null);
1261                            catPw.println();
1262                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1263                        }
1264                        dropBuilder.append(catSw.toString());
1265                        addErrorToDropBox("lowmem", null, "system_server", null,
1266                                null, tag.toString(), dropBuilder.toString(), null, null);
1267                        Slog.i(TAG, logBuilder.toString());
1268                        synchronized (ActivityManagerService.this) {
1269                            long now = SystemClock.uptimeMillis();
1270                            if (mLastMemUsageReportTime < now) {
1271                                mLastMemUsageReportTime = now;
1272                            }
1273                        }
1274                    }
1275                };
1276                thread.start();
1277                break;
1278            }
1279            }
1280        }
1281    };
1282
1283    public static void setSystemProcess() {
1284        try {
1285            ActivityManagerService m = mSelf;
1286
1287            ServiceManager.addService("activity", m, true);
1288            ServiceManager.addService("meminfo", new MemBinder(m));
1289            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1290            ServiceManager.addService("dbinfo", new DbBinder(m));
1291            if (MONITOR_CPU_USAGE) {
1292                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1293            }
1294            ServiceManager.addService("permission", new PermissionController(m));
1295
1296            ApplicationInfo info =
1297                mSelf.mContext.getPackageManager().getApplicationInfo(
1298                            "android", STOCK_PM_FLAGS);
1299            mSystemThread.installSystemApplicationInfo(info);
1300
1301            synchronized (mSelf) {
1302                ProcessRecord app = mSelf.newProcessRecordLocked(
1303                        mSystemThread.getApplicationThread(), info,
1304                        info.processName, false);
1305                app.persistent = true;
1306                app.pid = MY_PID;
1307                app.maxAdj = ProcessList.SYSTEM_ADJ;
1308                mSelf.mProcessNames.put(app.processName, app.uid, app);
1309                synchronized (mSelf.mPidsSelfLocked) {
1310                    mSelf.mPidsSelfLocked.put(app.pid, app);
1311                }
1312                mSelf.updateLruProcessLocked(app, true, true);
1313            }
1314        } catch (PackageManager.NameNotFoundException e) {
1315            throw new RuntimeException(
1316                    "Unable to find android system package", e);
1317        }
1318    }
1319
1320    public void setWindowManager(WindowManagerService wm) {
1321        mWindowManager = wm;
1322    }
1323
1324    public static final Context main(int factoryTest) {
1325        AThread thr = new AThread();
1326        thr.start();
1327
1328        synchronized (thr) {
1329            while (thr.mService == null) {
1330                try {
1331                    thr.wait();
1332                } catch (InterruptedException e) {
1333                }
1334            }
1335        }
1336
1337        ActivityManagerService m = thr.mService;
1338        mSelf = m;
1339        ActivityThread at = ActivityThread.systemMain();
1340        mSystemThread = at;
1341        Context context = at.getSystemContext();
1342        context.setTheme(android.R.style.Theme_Holo);
1343        m.mContext = context;
1344        m.mFactoryTest = factoryTest;
1345        m.mMainStack = new ActivityStack(m, context, true);
1346
1347        m.mBatteryStatsService.publish(context);
1348        m.mUsageStatsService.publish(context);
1349
1350        synchronized (thr) {
1351            thr.mReady = true;
1352            thr.notifyAll();
1353        }
1354
1355        m.startRunning(null, null, null, null);
1356
1357        return context;
1358    }
1359
1360    public static ActivityManagerService self() {
1361        return mSelf;
1362    }
1363
1364    static class AThread extends Thread {
1365        ActivityManagerService mService;
1366        boolean mReady = false;
1367
1368        public AThread() {
1369            super("ActivityManager");
1370        }
1371
1372        public void run() {
1373            Looper.prepare();
1374
1375            android.os.Process.setThreadPriority(
1376                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1377            android.os.Process.setCanSelfBackground(false);
1378
1379            ActivityManagerService m = new ActivityManagerService();
1380
1381            synchronized (this) {
1382                mService = m;
1383                notifyAll();
1384            }
1385
1386            synchronized (this) {
1387                while (!mReady) {
1388                    try {
1389                        wait();
1390                    } catch (InterruptedException e) {
1391                    }
1392                }
1393            }
1394
1395            // For debug builds, log event loop stalls to dropbox for analysis.
1396            if (StrictMode.conditionallyEnableDebugLogging()) {
1397                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1398            }
1399
1400            Looper.loop();
1401        }
1402    }
1403
1404    static class MemBinder extends Binder {
1405        ActivityManagerService mActivityManagerService;
1406        MemBinder(ActivityManagerService activityManagerService) {
1407            mActivityManagerService = activityManagerService;
1408        }
1409
1410        @Override
1411        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1412            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1413                    != PackageManager.PERMISSION_GRANTED) {
1414                pw.println("Permission Denial: can't dump meminfo from from pid="
1415                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1416                        + " without permission " + android.Manifest.permission.DUMP);
1417                return;
1418            }
1419
1420            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1421                    false, null, null, null);
1422        }
1423    }
1424
1425    static class GraphicsBinder extends Binder {
1426        ActivityManagerService mActivityManagerService;
1427        GraphicsBinder(ActivityManagerService activityManagerService) {
1428            mActivityManagerService = activityManagerService;
1429        }
1430
1431        @Override
1432        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1433            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1434                    != PackageManager.PERMISSION_GRANTED) {
1435                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1436                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1437                        + " without permission " + android.Manifest.permission.DUMP);
1438                return;
1439            }
1440
1441            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1442        }
1443    }
1444
1445    static class DbBinder extends Binder {
1446        ActivityManagerService mActivityManagerService;
1447        DbBinder(ActivityManagerService activityManagerService) {
1448            mActivityManagerService = activityManagerService;
1449        }
1450
1451        @Override
1452        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1453            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1454                    != PackageManager.PERMISSION_GRANTED) {
1455                pw.println("Permission Denial: can't dump dbinfo from from pid="
1456                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1457                        + " without permission " + android.Manifest.permission.DUMP);
1458                return;
1459            }
1460
1461            mActivityManagerService.dumpDbInfo(fd, pw, args);
1462        }
1463    }
1464
1465    static class CpuBinder extends Binder {
1466        ActivityManagerService mActivityManagerService;
1467        CpuBinder(ActivityManagerService activityManagerService) {
1468            mActivityManagerService = activityManagerService;
1469        }
1470
1471        @Override
1472        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1473            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1474                    != PackageManager.PERMISSION_GRANTED) {
1475                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1476                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1477                        + " without permission " + android.Manifest.permission.DUMP);
1478                return;
1479            }
1480
1481            synchronized (mActivityManagerService.mProcessStatsThread) {
1482                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1483                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1484                        SystemClock.uptimeMillis()));
1485            }
1486        }
1487    }
1488
1489    private ActivityManagerService() {
1490        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1491
1492        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1493        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1494        mBroadcastQueues[0] = mFgBroadcastQueue;
1495        mBroadcastQueues[1] = mBgBroadcastQueue;
1496
1497        mServices = new ActiveServices(this);
1498
1499        File dataDir = Environment.getDataDirectory();
1500        File systemDir = new File(dataDir, "system");
1501        systemDir.mkdirs();
1502        mBatteryStatsService = new BatteryStatsService(new File(
1503                systemDir, "batterystats.bin").toString());
1504        mBatteryStatsService.getActiveStatistics().readLocked();
1505        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1506        mOnBattery = DEBUG_POWER ? true
1507                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1508        mBatteryStatsService.getActiveStatistics().setCallback(this);
1509
1510        mUsageStatsService = new UsageStatsService(new File(
1511                systemDir, "usagestats").toString());
1512        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1513
1514        // User 0 is the first and only user that runs at boot.
1515        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1516
1517        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1518            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1519
1520        mConfiguration.setToDefaults();
1521        mConfiguration.locale = Locale.getDefault();
1522        mConfigurationSeq = mConfiguration.seq = 1;
1523        mProcessStats.init();
1524
1525        mCompatModePackages = new CompatModePackages(this, systemDir);
1526
1527        // Add ourself to the Watchdog monitors.
1528        Watchdog.getInstance().addMonitor(this);
1529
1530        mProcessStatsThread = new Thread("ProcessStats") {
1531            public void run() {
1532                while (true) {
1533                    try {
1534                        try {
1535                            synchronized(this) {
1536                                final long now = SystemClock.uptimeMillis();
1537                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1538                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1539                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1540                                //        + ", write delay=" + nextWriteDelay);
1541                                if (nextWriteDelay < nextCpuDelay) {
1542                                    nextCpuDelay = nextWriteDelay;
1543                                }
1544                                if (nextCpuDelay > 0) {
1545                                    mProcessStatsMutexFree.set(true);
1546                                    this.wait(nextCpuDelay);
1547                                }
1548                            }
1549                        } catch (InterruptedException e) {
1550                        }
1551                        updateCpuStatsNow();
1552                    } catch (Exception e) {
1553                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1554                    }
1555                }
1556            }
1557        };
1558        mProcessStatsThread.start();
1559    }
1560
1561    @Override
1562    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1563            throws RemoteException {
1564        if (code == SYSPROPS_TRANSACTION) {
1565            // We need to tell all apps about the system property change.
1566            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1567            synchronized(this) {
1568                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1569                    final int NA = apps.size();
1570                    for (int ia=0; ia<NA; ia++) {
1571                        ProcessRecord app = apps.valueAt(ia);
1572                        if (app.thread != null) {
1573                            procs.add(app.thread.asBinder());
1574                        }
1575                    }
1576                }
1577            }
1578
1579            int N = procs.size();
1580            for (int i=0; i<N; i++) {
1581                Parcel data2 = Parcel.obtain();
1582                try {
1583                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1584                } catch (RemoteException e) {
1585                }
1586                data2.recycle();
1587            }
1588        }
1589        try {
1590            return super.onTransact(code, data, reply, flags);
1591        } catch (RuntimeException e) {
1592            // The activity manager only throws security exceptions, so let's
1593            // log all others.
1594            if (!(e instanceof SecurityException)) {
1595                Slog.e(TAG, "Activity Manager Crash", e);
1596            }
1597            throw e;
1598        }
1599    }
1600
1601    void updateCpuStats() {
1602        final long now = SystemClock.uptimeMillis();
1603        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1604            return;
1605        }
1606        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1607            synchronized (mProcessStatsThread) {
1608                mProcessStatsThread.notify();
1609            }
1610        }
1611    }
1612
1613    void updateCpuStatsNow() {
1614        synchronized (mProcessStatsThread) {
1615            mProcessStatsMutexFree.set(false);
1616            final long now = SystemClock.uptimeMillis();
1617            boolean haveNewCpuStats = false;
1618
1619            if (MONITOR_CPU_USAGE &&
1620                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1621                mLastCpuTime.set(now);
1622                haveNewCpuStats = true;
1623                mProcessStats.update();
1624                //Slog.i(TAG, mProcessStats.printCurrentState());
1625                //Slog.i(TAG, "Total CPU usage: "
1626                //        + mProcessStats.getTotalCpuPercent() + "%");
1627
1628                // Slog the cpu usage if the property is set.
1629                if ("true".equals(SystemProperties.get("events.cpu"))) {
1630                    int user = mProcessStats.getLastUserTime();
1631                    int system = mProcessStats.getLastSystemTime();
1632                    int iowait = mProcessStats.getLastIoWaitTime();
1633                    int irq = mProcessStats.getLastIrqTime();
1634                    int softIrq = mProcessStats.getLastSoftIrqTime();
1635                    int idle = mProcessStats.getLastIdleTime();
1636
1637                    int total = user + system + iowait + irq + softIrq + idle;
1638                    if (total == 0) total = 1;
1639
1640                    EventLog.writeEvent(EventLogTags.CPU,
1641                            ((user+system+iowait+irq+softIrq) * 100) / total,
1642                            (user * 100) / total,
1643                            (system * 100) / total,
1644                            (iowait * 100) / total,
1645                            (irq * 100) / total,
1646                            (softIrq * 100) / total);
1647                }
1648            }
1649
1650            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1651            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1652            synchronized(bstats) {
1653                synchronized(mPidsSelfLocked) {
1654                    if (haveNewCpuStats) {
1655                        if (mOnBattery) {
1656                            int perc = bstats.startAddingCpuLocked();
1657                            int totalUTime = 0;
1658                            int totalSTime = 0;
1659                            final int N = mProcessStats.countStats();
1660                            for (int i=0; i<N; i++) {
1661                                ProcessStats.Stats st = mProcessStats.getStats(i);
1662                                if (!st.working) {
1663                                    continue;
1664                                }
1665                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1666                                int otherUTime = (st.rel_utime*perc)/100;
1667                                int otherSTime = (st.rel_stime*perc)/100;
1668                                totalUTime += otherUTime;
1669                                totalSTime += otherSTime;
1670                                if (pr != null) {
1671                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1672                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1673                                            st.rel_stime-otherSTime);
1674                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1675                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1676                                } else {
1677                                    BatteryStatsImpl.Uid.Proc ps =
1678                                            bstats.getProcessStatsLocked(st.name, st.pid);
1679                                    if (ps != null) {
1680                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1681                                                st.rel_stime-otherSTime);
1682                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1683                                    }
1684                                }
1685                            }
1686                            bstats.finishAddingCpuLocked(perc, totalUTime,
1687                                    totalSTime, cpuSpeedTimes);
1688                        }
1689                    }
1690                }
1691
1692                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1693                    mLastWriteTime = now;
1694                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1695                }
1696            }
1697        }
1698    }
1699
1700    @Override
1701    public void batteryNeedsCpuUpdate() {
1702        updateCpuStatsNow();
1703    }
1704
1705    @Override
1706    public void batteryPowerChanged(boolean onBattery) {
1707        // When plugging in, update the CPU stats first before changing
1708        // the plug state.
1709        updateCpuStatsNow();
1710        synchronized (this) {
1711            synchronized(mPidsSelfLocked) {
1712                mOnBattery = DEBUG_POWER ? true : onBattery;
1713            }
1714        }
1715    }
1716
1717    /**
1718     * Initialize the application bind args. These are passed to each
1719     * process when the bindApplication() IPC is sent to the process. They're
1720     * lazily setup to make sure the services are running when they're asked for.
1721     */
1722    private HashMap<String, IBinder> getCommonServicesLocked() {
1723        if (mAppBindArgs == null) {
1724            mAppBindArgs = new HashMap<String, IBinder>();
1725
1726            // Setup the application init args
1727            mAppBindArgs.put("package", ServiceManager.getService("package"));
1728            mAppBindArgs.put("window", ServiceManager.getService("window"));
1729            mAppBindArgs.put(Context.ALARM_SERVICE,
1730                    ServiceManager.getService(Context.ALARM_SERVICE));
1731        }
1732        return mAppBindArgs;
1733    }
1734
1735    final void setFocusedActivityLocked(ActivityRecord r) {
1736        if (mFocusedActivity != r) {
1737            mFocusedActivity = r;
1738            if (r != null) {
1739                mWindowManager.setFocusedApp(r.appToken, true);
1740            }
1741        }
1742    }
1743
1744    private final void updateLruProcessInternalLocked(ProcessRecord app,
1745            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1746        // put it on the LRU to keep track of when it should be exited.
1747        int lrui = mLruProcesses.indexOf(app);
1748        if (lrui >= 0) mLruProcesses.remove(lrui);
1749
1750        int i = mLruProcesses.size()-1;
1751        int skipTop = 0;
1752
1753        app.lruSeq = mLruSeq;
1754
1755        // compute the new weight for this process.
1756        if (updateActivityTime) {
1757            app.lastActivityTime = SystemClock.uptimeMillis();
1758        }
1759        if (app.activities.size() > 0) {
1760            // If this process has activities, we more strongly want to keep
1761            // it around.
1762            app.lruWeight = app.lastActivityTime;
1763        } else if (app.pubProviders.size() > 0) {
1764            // If this process contains content providers, we want to keep
1765            // it a little more strongly.
1766            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1767            // Also don't let it kick out the first few "real" hidden processes.
1768            skipTop = ProcessList.MIN_HIDDEN_APPS;
1769        } else {
1770            // If this process doesn't have activities, we less strongly
1771            // want to keep it around, and generally want to avoid getting
1772            // in front of any very recently used activities.
1773            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1774            // Also don't let it kick out the first few "real" hidden processes.
1775            skipTop = ProcessList.MIN_HIDDEN_APPS;
1776        }
1777
1778        while (i >= 0) {
1779            ProcessRecord p = mLruProcesses.get(i);
1780            // If this app shouldn't be in front of the first N background
1781            // apps, then skip over that many that are currently hidden.
1782            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1783                skipTop--;
1784            }
1785            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1786                mLruProcesses.add(i+1, app);
1787                break;
1788            }
1789            i--;
1790        }
1791        if (i < 0) {
1792            mLruProcesses.add(0, app);
1793        }
1794
1795        // If the app is currently using a content provider or service,
1796        // bump those processes as well.
1797        if (app.connections.size() > 0) {
1798            for (ConnectionRecord cr : app.connections) {
1799                if (cr.binding != null && cr.binding.service != null
1800                        && cr.binding.service.app != null
1801                        && cr.binding.service.app.lruSeq != mLruSeq) {
1802                    updateLruProcessInternalLocked(cr.binding.service.app, false,
1803                            updateActivityTime, i+1);
1804                }
1805            }
1806        }
1807        for (int j=app.conProviders.size()-1; j>=0; j--) {
1808            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1809            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1810                updateLruProcessInternalLocked(cpr.proc, false,
1811                        updateActivityTime, i+1);
1812            }
1813        }
1814
1815        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1816        if (oomAdj) {
1817            updateOomAdjLocked();
1818        }
1819    }
1820
1821    final void updateLruProcessLocked(ProcessRecord app,
1822            boolean oomAdj, boolean updateActivityTime) {
1823        mLruSeq++;
1824        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1825    }
1826
1827    final ProcessRecord getProcessRecordLocked(
1828            String processName, int uid) {
1829        if (uid == Process.SYSTEM_UID) {
1830            // The system gets to run in any process.  If there are multiple
1831            // processes with the same uid, just pick the first (this
1832            // should never happen).
1833            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1834                    processName);
1835            if (procs == null) return null;
1836            final int N = procs.size();
1837            for (int i = 0; i < N; i++) {
1838                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1839            }
1840        }
1841        ProcessRecord proc = mProcessNames.get(processName, uid);
1842        return proc;
1843    }
1844
1845    void ensurePackageDexOpt(String packageName) {
1846        IPackageManager pm = AppGlobals.getPackageManager();
1847        try {
1848            if (pm.performDexOpt(packageName)) {
1849                mDidDexOpt = true;
1850            }
1851        } catch (RemoteException e) {
1852        }
1853    }
1854
1855    boolean isNextTransitionForward() {
1856        int transit = mWindowManager.getPendingAppTransition();
1857        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1858                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1859                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1860    }
1861
1862    final ProcessRecord startProcessLocked(String processName,
1863            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1864            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1865            boolean isolated) {
1866        ProcessRecord app;
1867        if (!isolated) {
1868            app = getProcessRecordLocked(processName, info.uid);
1869        } else {
1870            // If this is an isolated process, it can't re-use an existing process.
1871            app = null;
1872        }
1873        // We don't have to do anything more if:
1874        // (1) There is an existing application record; and
1875        // (2) The caller doesn't think it is dead, OR there is no thread
1876        //     object attached to it so we know it couldn't have crashed; and
1877        // (3) There is a pid assigned to it, so it is either starting or
1878        //     already running.
1879        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1880                + " app=" + app + " knownToBeDead=" + knownToBeDead
1881                + " thread=" + (app != null ? app.thread : null)
1882                + " pid=" + (app != null ? app.pid : -1));
1883        if (app != null && app.pid > 0) {
1884            if (!knownToBeDead || app.thread == null) {
1885                // We already have the app running, or are waiting for it to
1886                // come up (we have a pid but not yet its thread), so keep it.
1887                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1888                // If this is a new package in the process, add the package to the list
1889                app.addPackage(info.packageName);
1890                return app;
1891            } else {
1892                // An application record is attached to a previous process,
1893                // clean it up now.
1894                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1895                handleAppDiedLocked(app, true, true);
1896            }
1897        }
1898
1899        String hostingNameStr = hostingName != null
1900                ? hostingName.flattenToShortString() : null;
1901
1902        if (!isolated) {
1903            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1904                // If we are in the background, then check to see if this process
1905                // is bad.  If so, we will just silently fail.
1906                if (mBadProcesses.get(info.processName, info.uid) != null) {
1907                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1908                            + "/" + info.processName);
1909                    return null;
1910                }
1911            } else {
1912                // When the user is explicitly starting a process, then clear its
1913                // crash count so that we won't make it bad until they see at
1914                // least one crash dialog again, and make the process good again
1915                // if it had been bad.
1916                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1917                        + "/" + info.processName);
1918                mProcessCrashTimes.remove(info.processName, info.uid);
1919                if (mBadProcesses.get(info.processName, info.uid) != null) {
1920                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1921                            info.processName);
1922                    mBadProcesses.remove(info.processName, info.uid);
1923                    if (app != null) {
1924                        app.bad = false;
1925                    }
1926                }
1927            }
1928        }
1929
1930        if (app == null) {
1931            app = newProcessRecordLocked(null, info, processName, isolated);
1932            if (app == null) {
1933                Slog.w(TAG, "Failed making new process record for "
1934                        + processName + "/" + info.uid + " isolated=" + isolated);
1935                return null;
1936            }
1937            mProcessNames.put(processName, app.uid, app);
1938            if (isolated) {
1939                mIsolatedProcesses.put(app.uid, app);
1940            }
1941        } else {
1942            // If this is a new package in the process, add the package to the list
1943            app.addPackage(info.packageName);
1944        }
1945
1946        // If the system is not ready yet, then hold off on starting this
1947        // process until it is.
1948        if (!mProcessesReady
1949                && !isAllowedWhileBooting(info)
1950                && !allowWhileBooting) {
1951            if (!mProcessesOnHold.contains(app)) {
1952                mProcessesOnHold.add(app);
1953            }
1954            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1955            return app;
1956        }
1957
1958        startProcessLocked(app, hostingType, hostingNameStr);
1959        return (app.pid != 0) ? app : null;
1960    }
1961
1962    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1963        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1964    }
1965
1966    private final void startProcessLocked(ProcessRecord app,
1967            String hostingType, String hostingNameStr) {
1968        if (app.pid > 0 && app.pid != MY_PID) {
1969            synchronized (mPidsSelfLocked) {
1970                mPidsSelfLocked.remove(app.pid);
1971                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1972            }
1973            app.setPid(0);
1974        }
1975
1976        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1977                "startProcessLocked removing on hold: " + app);
1978        mProcessesOnHold.remove(app);
1979
1980        updateCpuStats();
1981
1982        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1983        mProcDeaths[0] = 0;
1984
1985        try {
1986            int uid = app.uid;
1987
1988            int[] gids = null;
1989            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
1990            if (!app.isolated) {
1991                try {
1992                    final PackageManager pm = mContext.getPackageManager();
1993                    gids = pm.getPackageGids(app.info.packageName);
1994
1995                    if (Environment.isExternalStorageEmulated()) {
1996                        if (pm.checkPermission(
1997                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
1998                                app.info.packageName) == PERMISSION_GRANTED) {
1999                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2000                        } else {
2001                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2002                        }
2003                    }
2004                } catch (PackageManager.NameNotFoundException e) {
2005                    Slog.w(TAG, "Unable to retrieve gids", e);
2006                }
2007            }
2008            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2009                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2010                        && mTopComponent != null
2011                        && app.processName.equals(mTopComponent.getPackageName())) {
2012                    uid = 0;
2013                }
2014                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2015                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2016                    uid = 0;
2017                }
2018            }
2019            int debugFlags = 0;
2020            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2021                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2022                // Also turn on CheckJNI for debuggable apps. It's quite
2023                // awkward to turn on otherwise.
2024                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2025            }
2026            // Run the app in safe mode if its manifest requests so or the
2027            // system is booted in safe mode.
2028            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2029                Zygote.systemInSafeMode == true) {
2030                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2031            }
2032            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2033                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2034            }
2035            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2036                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2037            }
2038            if ("1".equals(SystemProperties.get("debug.assert"))) {
2039                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2040            }
2041
2042            // Start the process.  It will either succeed and return a result containing
2043            // the PID of the new process, or else throw a RuntimeException.
2044            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2045                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2046                    app.info.targetSdkVersion, null, null);
2047
2048            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2049            synchronized (bs) {
2050                if (bs.isOnBattery()) {
2051                    app.batteryStats.incStartsLocked();
2052                }
2053            }
2054
2055            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2056                    app.processName, hostingType,
2057                    hostingNameStr != null ? hostingNameStr : "");
2058
2059            if (app.persistent) {
2060                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2061            }
2062
2063            StringBuilder buf = mStringBuilder;
2064            buf.setLength(0);
2065            buf.append("Start proc ");
2066            buf.append(app.processName);
2067            buf.append(" for ");
2068            buf.append(hostingType);
2069            if (hostingNameStr != null) {
2070                buf.append(" ");
2071                buf.append(hostingNameStr);
2072            }
2073            buf.append(": pid=");
2074            buf.append(startResult.pid);
2075            buf.append(" uid=");
2076            buf.append(uid);
2077            buf.append(" gids={");
2078            if (gids != null) {
2079                for (int gi=0; gi<gids.length; gi++) {
2080                    if (gi != 0) buf.append(", ");
2081                    buf.append(gids[gi]);
2082
2083                }
2084            }
2085            buf.append("}");
2086            Slog.i(TAG, buf.toString());
2087            app.setPid(startResult.pid);
2088            app.usingWrapper = startResult.usingWrapper;
2089            app.removed = false;
2090            synchronized (mPidsSelfLocked) {
2091                this.mPidsSelfLocked.put(startResult.pid, app);
2092                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2093                msg.obj = app;
2094                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2095                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2096            }
2097        } catch (RuntimeException e) {
2098            // XXX do better error recovery.
2099            app.setPid(0);
2100            Slog.e(TAG, "Failure starting process " + app.processName, e);
2101        }
2102    }
2103
2104    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2105        if (resumed) {
2106            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2107        } else {
2108            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2109        }
2110    }
2111
2112    boolean startHomeActivityLocked(int userId, UserStartedState startingUser) {
2113        if (mHeadless) {
2114            // Added because none of the other calls to ensureBootCompleted seem to fire
2115            // when running headless.
2116            ensureBootCompleted();
2117            return false;
2118        }
2119
2120        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2121                && mTopAction == null) {
2122            // We are running in factory test mode, but unable to find
2123            // the factory test app, so just sit around displaying the
2124            // error message and don't try to start anything.
2125            return false;
2126        }
2127        Intent intent = new Intent(
2128            mTopAction,
2129            mTopData != null ? Uri.parse(mTopData) : null);
2130        intent.setComponent(mTopComponent);
2131        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2132            intent.addCategory(Intent.CATEGORY_HOME);
2133        }
2134        ActivityInfo aInfo =
2135            intent.resolveActivityInfo(mContext.getPackageManager(),
2136                    STOCK_PM_FLAGS);
2137        if (aInfo != null) {
2138            intent.setComponent(new ComponentName(
2139                    aInfo.applicationInfo.packageName, aInfo.name));
2140            // Don't do this if the home app is currently being
2141            // instrumented.
2142            aInfo = new ActivityInfo(aInfo);
2143            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2144            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2145                    aInfo.applicationInfo.uid);
2146            if (app == null || app.instrumentationClass == null) {
2147                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2148                mMainStack.startActivityLocked(null, intent, null, aInfo,
2149                        null, null, 0, 0, 0, 0, null, false, null);
2150            }
2151        }
2152        if (startingUser != null) {
2153            mMainStack.addStartingUserLocked(startingUser);
2154        }
2155
2156        return true;
2157    }
2158
2159    /**
2160     * Starts the "new version setup screen" if appropriate.
2161     */
2162    void startSetupActivityLocked() {
2163        // Only do this once per boot.
2164        if (mCheckedForSetup) {
2165            return;
2166        }
2167
2168        // We will show this screen if the current one is a different
2169        // version than the last one shown, and we are not running in
2170        // low-level factory test mode.
2171        final ContentResolver resolver = mContext.getContentResolver();
2172        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2173                Settings.Secure.getInt(resolver,
2174                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2175            mCheckedForSetup = true;
2176
2177            // See if we should be showing the platform update setup UI.
2178            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2179            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2180                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2181
2182            // We don't allow third party apps to replace this.
2183            ResolveInfo ri = null;
2184            for (int i=0; ris != null && i<ris.size(); i++) {
2185                if ((ris.get(i).activityInfo.applicationInfo.flags
2186                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2187                    ri = ris.get(i);
2188                    break;
2189                }
2190            }
2191
2192            if (ri != null) {
2193                String vers = ri.activityInfo.metaData != null
2194                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2195                        : null;
2196                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2197                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2198                            Intent.METADATA_SETUP_VERSION);
2199                }
2200                String lastVers = Settings.Secure.getString(
2201                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2202                if (vers != null && !vers.equals(lastVers)) {
2203                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2204                    intent.setComponent(new ComponentName(
2205                            ri.activityInfo.packageName, ri.activityInfo.name));
2206                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2207                            null, null, 0, 0, 0, 0, null, false, null);
2208                }
2209            }
2210        }
2211    }
2212
2213    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2214        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2215    }
2216
2217    void enforceNotIsolatedCaller(String caller) {
2218        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2219            throw new SecurityException("Isolated process not allowed to call " + caller);
2220        }
2221    }
2222
2223    public int getFrontActivityScreenCompatMode() {
2224        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2225        synchronized (this) {
2226            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2227        }
2228    }
2229
2230    public void setFrontActivityScreenCompatMode(int mode) {
2231        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2232                "setFrontActivityScreenCompatMode");
2233        synchronized (this) {
2234            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2235        }
2236    }
2237
2238    public int getPackageScreenCompatMode(String packageName) {
2239        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2240        synchronized (this) {
2241            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2242        }
2243    }
2244
2245    public void setPackageScreenCompatMode(String packageName, int mode) {
2246        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2247                "setPackageScreenCompatMode");
2248        synchronized (this) {
2249            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2250        }
2251    }
2252
2253    public boolean getPackageAskScreenCompat(String packageName) {
2254        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2255        synchronized (this) {
2256            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2257        }
2258    }
2259
2260    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2261        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2262                "setPackageAskScreenCompat");
2263        synchronized (this) {
2264            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2265        }
2266    }
2267
2268    void reportResumedActivityLocked(ActivityRecord r) {
2269        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2270        updateUsageStats(r, true);
2271    }
2272
2273    private void dispatchProcessesChanged() {
2274        int N;
2275        synchronized (this) {
2276            N = mPendingProcessChanges.size();
2277            if (mActiveProcessChanges.length < N) {
2278                mActiveProcessChanges = new ProcessChangeItem[N];
2279            }
2280            mPendingProcessChanges.toArray(mActiveProcessChanges);
2281            mAvailProcessChanges.addAll(mPendingProcessChanges);
2282            mPendingProcessChanges.clear();
2283            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2284        }
2285        int i = mProcessObservers.beginBroadcast();
2286        while (i > 0) {
2287            i--;
2288            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2289            if (observer != null) {
2290                try {
2291                    for (int j=0; j<N; j++) {
2292                        ProcessChangeItem item = mActiveProcessChanges[j];
2293                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2294                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2295                                    + item.pid + " uid=" + item.uid + ": "
2296                                    + item.foregroundActivities);
2297                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2298                                    item.foregroundActivities);
2299                        }
2300                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2301                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2302                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2303                            observer.onImportanceChanged(item.pid, item.uid,
2304                                    item.importance);
2305                        }
2306                    }
2307                } catch (RemoteException e) {
2308                }
2309            }
2310        }
2311        mProcessObservers.finishBroadcast();
2312    }
2313
2314    private void dispatchProcessDied(int pid, int uid) {
2315        int i = mProcessObservers.beginBroadcast();
2316        while (i > 0) {
2317            i--;
2318            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2319            if (observer != null) {
2320                try {
2321                    observer.onProcessDied(pid, uid);
2322                } catch (RemoteException e) {
2323                }
2324            }
2325        }
2326        mProcessObservers.finishBroadcast();
2327    }
2328
2329    final void doPendingActivityLaunchesLocked(boolean doResume) {
2330        final int N = mPendingActivityLaunches.size();
2331        if (N <= 0) {
2332            return;
2333        }
2334        for (int i=0; i<N; i++) {
2335            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2336            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2337                    pal.startFlags, doResume && i == (N-1), null);
2338        }
2339        mPendingActivityLaunches.clear();
2340    }
2341
2342    public final int startActivity(IApplicationThread caller,
2343            Intent intent, String resolvedType, IBinder resultTo,
2344            String resultWho, int requestCode, int startFlags,
2345            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2346        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2347                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2348    }
2349
2350    public final int startActivityAsUser(IApplicationThread caller,
2351            Intent intent, String resolvedType, IBinder resultTo,
2352            String resultWho, int requestCode, int startFlags,
2353            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2354        enforceNotIsolatedCaller("startActivity");
2355        if (userId != UserHandle.getCallingUserId()) {
2356            // Requesting a different user, make sure that they have the permission
2357            if (checkComponentPermission(
2358                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2359                    Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
2360                    == PackageManager.PERMISSION_GRANTED) {
2361                // Translate to the current user id, if caller wasn't aware
2362                if (userId == UserHandle.USER_CURRENT) {
2363                    userId = mCurrentUserId;
2364                }
2365            } else {
2366                String msg = "Permission Denial: "
2367                        + "Request to startActivity as user " + userId
2368                        + " but is calling from user " + UserHandle.getCallingUserId()
2369                        + "; this requires "
2370                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
2371                Slog.w(TAG, msg);
2372                throw new SecurityException(msg);
2373            }
2374        } else {
2375            if (intent.getCategories() != null
2376                    && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2377                // Requesting home, set the identity to the current user
2378                // HACK!
2379                userId = mCurrentUserId;
2380            } else {
2381                // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
2382                // the current user's userId
2383                if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
2384                    userId = 0;
2385                } else {
2386                    userId = Binder.getOrigCallingUser();
2387                }
2388            }
2389        }
2390        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2391                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2392                null, null, options, userId);
2393    }
2394
2395    public final WaitResult startActivityAndWait(IApplicationThread caller,
2396            Intent intent, String resolvedType, IBinder resultTo,
2397            String resultWho, int requestCode, int startFlags, String profileFile,
2398            ParcelFileDescriptor profileFd, Bundle options) {
2399        enforceNotIsolatedCaller("startActivityAndWait");
2400        WaitResult res = new WaitResult();
2401        int userId = Binder.getOrigCallingUser();
2402        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2403                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2404                res, null, options, userId);
2405        return res;
2406    }
2407
2408    public final int startActivityWithConfig(IApplicationThread caller,
2409            Intent intent, String resolvedType, IBinder resultTo,
2410            String resultWho, int requestCode, int startFlags, Configuration config,
2411            Bundle options) {
2412        enforceNotIsolatedCaller("startActivityWithConfig");
2413        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2414                resultTo, resultWho, requestCode, startFlags,
2415                null, null, null, config, options, Binder.getOrigCallingUser());
2416        return ret;
2417    }
2418
2419    public int startActivityIntentSender(IApplicationThread caller,
2420            IntentSender intent, Intent fillInIntent, String resolvedType,
2421            IBinder resultTo, String resultWho, int requestCode,
2422            int flagsMask, int flagsValues, Bundle options) {
2423        enforceNotIsolatedCaller("startActivityIntentSender");
2424        // Refuse possible leaked file descriptors
2425        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2426            throw new IllegalArgumentException("File descriptors passed in Intent");
2427        }
2428
2429        IIntentSender sender = intent.getTarget();
2430        if (!(sender instanceof PendingIntentRecord)) {
2431            throw new IllegalArgumentException("Bad PendingIntent object");
2432        }
2433
2434        PendingIntentRecord pir = (PendingIntentRecord)sender;
2435
2436        synchronized (this) {
2437            // If this is coming from the currently resumed activity, it is
2438            // effectively saying that app switches are allowed at this point.
2439            if (mMainStack.mResumedActivity != null
2440                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2441                            Binder.getCallingUid()) {
2442                mAppSwitchesAllowedTime = 0;
2443            }
2444        }
2445        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2446                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2447        return ret;
2448    }
2449
2450    public boolean startNextMatchingActivity(IBinder callingActivity,
2451            Intent intent, Bundle options) {
2452        // Refuse possible leaked file descriptors
2453        if (intent != null && intent.hasFileDescriptors() == true) {
2454            throw new IllegalArgumentException("File descriptors passed in Intent");
2455        }
2456
2457        synchronized (this) {
2458            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2459            if (r == null) {
2460                ActivityOptions.abort(options);
2461                return false;
2462            }
2463            if (r.app == null || r.app.thread == null) {
2464                // The caller is not running...  d'oh!
2465                ActivityOptions.abort(options);
2466                return false;
2467            }
2468            intent = new Intent(intent);
2469            // The caller is not allowed to change the data.
2470            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2471            // And we are resetting to find the next component...
2472            intent.setComponent(null);
2473
2474            ActivityInfo aInfo = null;
2475            try {
2476                List<ResolveInfo> resolves =
2477                    AppGlobals.getPackageManager().queryIntentActivities(
2478                            intent, r.resolvedType,
2479                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2480                            UserHandle.getCallingUserId());
2481
2482                // Look for the original activity in the list...
2483                final int N = resolves != null ? resolves.size() : 0;
2484                for (int i=0; i<N; i++) {
2485                    ResolveInfo rInfo = resolves.get(i);
2486                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2487                            && rInfo.activityInfo.name.equals(r.info.name)) {
2488                        // We found the current one...  the next matching is
2489                        // after it.
2490                        i++;
2491                        if (i<N) {
2492                            aInfo = resolves.get(i).activityInfo;
2493                        }
2494                        break;
2495                    }
2496                }
2497            } catch (RemoteException e) {
2498            }
2499
2500            if (aInfo == null) {
2501                // Nobody who is next!
2502                ActivityOptions.abort(options);
2503                return false;
2504            }
2505
2506            intent.setComponent(new ComponentName(
2507                    aInfo.applicationInfo.packageName, aInfo.name));
2508            intent.setFlags(intent.getFlags()&~(
2509                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2510                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2511                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2512                    Intent.FLAG_ACTIVITY_NEW_TASK));
2513
2514            // Okay now we need to start the new activity, replacing the
2515            // currently running activity.  This is a little tricky because
2516            // we want to start the new one as if the current one is finished,
2517            // but not finish the current one first so that there is no flicker.
2518            // And thus...
2519            final boolean wasFinishing = r.finishing;
2520            r.finishing = true;
2521
2522            // Propagate reply information over to the new activity.
2523            final ActivityRecord resultTo = r.resultTo;
2524            final String resultWho = r.resultWho;
2525            final int requestCode = r.requestCode;
2526            r.resultTo = null;
2527            if (resultTo != null) {
2528                resultTo.removeResultsLocked(r, resultWho, requestCode);
2529            }
2530
2531            final long origId = Binder.clearCallingIdentity();
2532            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2533                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2534                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2535                    options, false, null);
2536            Binder.restoreCallingIdentity(origId);
2537
2538            r.finishing = wasFinishing;
2539            if (res != ActivityManager.START_SUCCESS) {
2540                return false;
2541            }
2542            return true;
2543        }
2544    }
2545
2546    public final int startActivityInPackage(int uid,
2547            Intent intent, String resolvedType, IBinder resultTo,
2548            String resultWho, int requestCode, int startFlags, Bundle options) {
2549
2550        // This is so super not safe, that only the system (or okay root)
2551        // can do it.
2552        final int callingUid = Binder.getCallingUid();
2553        if (callingUid != 0 && callingUid != Process.myUid()) {
2554            throw new SecurityException(
2555                    "startActivityInPackage only available to the system");
2556        }
2557
2558        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2559                resultTo, resultWho, requestCode, startFlags,
2560                null, null, null, null, options, UserHandle.getUserId(uid));
2561        return ret;
2562    }
2563
2564    public final int startActivities(IApplicationThread caller,
2565            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2566        enforceNotIsolatedCaller("startActivities");
2567        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2568                options, Binder.getOrigCallingUser());
2569        return ret;
2570    }
2571
2572    public final int startActivitiesInPackage(int uid,
2573            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2574            Bundle options) {
2575
2576        // This is so super not safe, that only the system (or okay root)
2577        // can do it.
2578        final int callingUid = Binder.getCallingUid();
2579        if (callingUid != 0 && callingUid != Process.myUid()) {
2580            throw new SecurityException(
2581                    "startActivityInPackage only available to the system");
2582        }
2583        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2584                options, UserHandle.getUserId(uid));
2585        return ret;
2586    }
2587
2588    final void addRecentTaskLocked(TaskRecord task) {
2589        int N = mRecentTasks.size();
2590        // Quick case: check if the top-most recent task is the same.
2591        if (N > 0 && mRecentTasks.get(0) == task) {
2592            return;
2593        }
2594        // Remove any existing entries that are the same kind of task.
2595        for (int i=0; i<N; i++) {
2596            TaskRecord tr = mRecentTasks.get(i);
2597            if (task.userId == tr.userId
2598                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2599                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2600                mRecentTasks.remove(i);
2601                i--;
2602                N--;
2603                if (task.intent == null) {
2604                    // If the new recent task we are adding is not fully
2605                    // specified, then replace it with the existing recent task.
2606                    task = tr;
2607                }
2608            }
2609        }
2610        if (N >= MAX_RECENT_TASKS) {
2611            mRecentTasks.remove(N-1);
2612        }
2613        mRecentTasks.add(0, task);
2614    }
2615
2616    public void setRequestedOrientation(IBinder token,
2617            int requestedOrientation) {
2618        synchronized (this) {
2619            ActivityRecord r = mMainStack.isInStackLocked(token);
2620            if (r == null) {
2621                return;
2622            }
2623            final long origId = Binder.clearCallingIdentity();
2624            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2625            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2626                    mConfiguration,
2627                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2628            if (config != null) {
2629                r.frozenBeforeDestroy = true;
2630                if (!updateConfigurationLocked(config, r, false, false)) {
2631                    mMainStack.resumeTopActivityLocked(null);
2632                }
2633            }
2634            Binder.restoreCallingIdentity(origId);
2635        }
2636    }
2637
2638    public int getRequestedOrientation(IBinder token) {
2639        synchronized (this) {
2640            ActivityRecord r = mMainStack.isInStackLocked(token);
2641            if (r == null) {
2642                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2643            }
2644            return mWindowManager.getAppOrientation(r.appToken);
2645        }
2646    }
2647
2648    /**
2649     * This is the internal entry point for handling Activity.finish().
2650     *
2651     * @param token The Binder token referencing the Activity we want to finish.
2652     * @param resultCode Result code, if any, from this Activity.
2653     * @param resultData Result data (Intent), if any, from this Activity.
2654     *
2655     * @return Returns true if the activity successfully finished, or false if it is still running.
2656     */
2657    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2658        // Refuse possible leaked file descriptors
2659        if (resultData != null && resultData.hasFileDescriptors() == true) {
2660            throw new IllegalArgumentException("File descriptors passed in Intent");
2661        }
2662
2663        synchronized(this) {
2664            if (mController != null) {
2665                // Find the first activity that is not finishing.
2666                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2667                if (next != null) {
2668                    // ask watcher if this is allowed
2669                    boolean resumeOK = true;
2670                    try {
2671                        resumeOK = mController.activityResuming(next.packageName);
2672                    } catch (RemoteException e) {
2673                        mController = null;
2674                    }
2675
2676                    if (!resumeOK) {
2677                        return false;
2678                    }
2679                }
2680            }
2681            final long origId = Binder.clearCallingIdentity();
2682            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2683                    resultData, "app-request");
2684            Binder.restoreCallingIdentity(origId);
2685            return res;
2686        }
2687    }
2688
2689    public final void finishHeavyWeightApp() {
2690        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2691                != PackageManager.PERMISSION_GRANTED) {
2692            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2693                    + Binder.getCallingPid()
2694                    + ", uid=" + Binder.getCallingUid()
2695                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2696            Slog.w(TAG, msg);
2697            throw new SecurityException(msg);
2698        }
2699
2700        synchronized(this) {
2701            if (mHeavyWeightProcess == null) {
2702                return;
2703            }
2704
2705            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2706                    mHeavyWeightProcess.activities);
2707            for (int i=0; i<activities.size(); i++) {
2708                ActivityRecord r = activities.get(i);
2709                if (!r.finishing) {
2710                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2711                    if (index >= 0) {
2712                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2713                                null, "finish-heavy");
2714                    }
2715                }
2716            }
2717
2718            mHeavyWeightProcess = null;
2719            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2720        }
2721    }
2722
2723    public void crashApplication(int uid, int initialPid, String packageName,
2724            String message) {
2725        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2726                != PackageManager.PERMISSION_GRANTED) {
2727            String msg = "Permission Denial: crashApplication() from pid="
2728                    + Binder.getCallingPid()
2729                    + ", uid=" + Binder.getCallingUid()
2730                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2731            Slog.w(TAG, msg);
2732            throw new SecurityException(msg);
2733        }
2734
2735        synchronized(this) {
2736            ProcessRecord proc = null;
2737
2738            // Figure out which process to kill.  We don't trust that initialPid
2739            // still has any relation to current pids, so must scan through the
2740            // list.
2741            synchronized (mPidsSelfLocked) {
2742                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2743                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2744                    if (p.uid != uid) {
2745                        continue;
2746                    }
2747                    if (p.pid == initialPid) {
2748                        proc = p;
2749                        break;
2750                    }
2751                    for (String str : p.pkgList) {
2752                        if (str.equals(packageName)) {
2753                            proc = p;
2754                        }
2755                    }
2756                }
2757            }
2758
2759            if (proc == null) {
2760                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2761                        + " initialPid=" + initialPid
2762                        + " packageName=" + packageName);
2763                return;
2764            }
2765
2766            if (proc.thread != null) {
2767                if (proc.pid == Process.myPid()) {
2768                    Log.w(TAG, "crashApplication: trying to crash self!");
2769                    return;
2770                }
2771                long ident = Binder.clearCallingIdentity();
2772                try {
2773                    proc.thread.scheduleCrash(message);
2774                } catch (RemoteException e) {
2775                }
2776                Binder.restoreCallingIdentity(ident);
2777            }
2778        }
2779    }
2780
2781    public final void finishSubActivity(IBinder token, String resultWho,
2782            int requestCode) {
2783        synchronized(this) {
2784            final long origId = Binder.clearCallingIdentity();
2785            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2786            Binder.restoreCallingIdentity(origId);
2787        }
2788    }
2789
2790    public boolean finishActivityAffinity(IBinder token) {
2791        synchronized(this) {
2792            final long origId = Binder.clearCallingIdentity();
2793            boolean res = mMainStack.finishActivityAffinityLocked(token);
2794            Binder.restoreCallingIdentity(origId);
2795            return res;
2796        }
2797    }
2798
2799    public boolean willActivityBeVisible(IBinder token) {
2800        synchronized(this) {
2801            int i;
2802            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2803                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2804                if (r.appToken == token) {
2805                    return true;
2806                }
2807                if (r.fullscreen && !r.finishing) {
2808                    return false;
2809                }
2810            }
2811            return true;
2812        }
2813    }
2814
2815    public void overridePendingTransition(IBinder token, String packageName,
2816            int enterAnim, int exitAnim) {
2817        synchronized(this) {
2818            ActivityRecord self = mMainStack.isInStackLocked(token);
2819            if (self == null) {
2820                return;
2821            }
2822
2823            final long origId = Binder.clearCallingIdentity();
2824
2825            if (self.state == ActivityState.RESUMED
2826                    || self.state == ActivityState.PAUSING) {
2827                mWindowManager.overridePendingAppTransition(packageName,
2828                        enterAnim, exitAnim, null);
2829            }
2830
2831            Binder.restoreCallingIdentity(origId);
2832        }
2833    }
2834
2835    /**
2836     * Main function for removing an existing process from the activity manager
2837     * as a result of that process going away.  Clears out all connections
2838     * to the process.
2839     */
2840    private final void handleAppDiedLocked(ProcessRecord app,
2841            boolean restarting, boolean allowRestart) {
2842        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2843        if (!restarting) {
2844            mLruProcesses.remove(app);
2845        }
2846
2847        if (mProfileProc == app) {
2848            clearProfilerLocked();
2849        }
2850
2851        // Just in case...
2852        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2853            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2854            mMainStack.mPausingActivity = null;
2855        }
2856        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2857            mMainStack.mLastPausedActivity = null;
2858        }
2859
2860        // Remove this application's activities from active lists.
2861        mMainStack.removeHistoryRecordsForAppLocked(app);
2862
2863        boolean atTop = true;
2864        boolean hasVisibleActivities = false;
2865
2866        // Clean out the history list.
2867        int i = mMainStack.mHistory.size();
2868        if (localLOGV) Slog.v(
2869            TAG, "Removing app " + app + " from history with " + i + " entries");
2870        while (i > 0) {
2871            i--;
2872            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2873            if (localLOGV) Slog.v(
2874                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2875            if (r.app == app) {
2876                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2877                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2878                        RuntimeException here = new RuntimeException("here");
2879                        here.fillInStackTrace();
2880                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2881                                + ": haveState=" + r.haveState
2882                                + " stateNotNeeded=" + r.stateNotNeeded
2883                                + " finishing=" + r.finishing
2884                                + " state=" + r.state, here);
2885                    }
2886                    if (!r.finishing) {
2887                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2888                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2889                                System.identityHashCode(r),
2890                                r.task.taskId, r.shortComponentName,
2891                                "proc died without state saved");
2892                    }
2893                    mMainStack.removeActivityFromHistoryLocked(r);
2894
2895                } else {
2896                    // We have the current state for this activity, so
2897                    // it can be restarted later when needed.
2898                    if (localLOGV) Slog.v(
2899                        TAG, "Keeping entry, setting app to null");
2900                    if (r.visible) {
2901                        hasVisibleActivities = true;
2902                    }
2903                    r.app = null;
2904                    r.nowVisible = false;
2905                    if (!r.haveState) {
2906                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2907                                "App died, clearing saved state of " + r);
2908                        r.icicle = null;
2909                    }
2910                }
2911
2912                r.stack.cleanUpActivityLocked(r, true, true);
2913            }
2914            atTop = false;
2915        }
2916
2917        app.activities.clear();
2918
2919        if (app.instrumentationClass != null) {
2920            Slog.w(TAG, "Crash of app " + app.processName
2921                  + " running instrumentation " + app.instrumentationClass);
2922            Bundle info = new Bundle();
2923            info.putString("shortMsg", "Process crashed.");
2924            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2925        }
2926
2927        if (!restarting) {
2928            if (!mMainStack.resumeTopActivityLocked(null)) {
2929                // If there was nothing to resume, and we are not already
2930                // restarting this process, but there is a visible activity that
2931                // is hosted by the process...  then make sure all visible
2932                // activities are running, taking care of restarting this
2933                // process.
2934                if (hasVisibleActivities) {
2935                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2936                }
2937            }
2938        }
2939    }
2940
2941    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2942        IBinder threadBinder = thread.asBinder();
2943        // Find the application record.
2944        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2945            ProcessRecord rec = mLruProcesses.get(i);
2946            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2947                return i;
2948            }
2949        }
2950        return -1;
2951    }
2952
2953    final ProcessRecord getRecordForAppLocked(
2954            IApplicationThread thread) {
2955        if (thread == null) {
2956            return null;
2957        }
2958
2959        int appIndex = getLRURecordIndexForAppLocked(thread);
2960        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2961    }
2962
2963    final void appDiedLocked(ProcessRecord app, int pid,
2964            IApplicationThread thread) {
2965
2966        mProcDeaths[0]++;
2967
2968        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2969        synchronized (stats) {
2970            stats.noteProcessDiedLocked(app.info.uid, pid);
2971        }
2972
2973        // Clean up already done if the process has been re-started.
2974        if (app.pid == pid && app.thread != null &&
2975                app.thread.asBinder() == thread.asBinder()) {
2976            if (!app.killedBackground) {
2977                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2978                        + ") has died.");
2979            }
2980            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2981            if (localLOGV) Slog.v(
2982                TAG, "Dying app: " + app + ", pid: " + pid
2983                + ", thread: " + thread.asBinder());
2984            boolean doLowMem = app.instrumentationClass == null;
2985            handleAppDiedLocked(app, false, true);
2986
2987            if (doLowMem) {
2988                // If there are no longer any background processes running,
2989                // and the app that died was not running instrumentation,
2990                // then tell everyone we are now low on memory.
2991                boolean haveBg = false;
2992                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2993                    ProcessRecord rec = mLruProcesses.get(i);
2994                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2995                        haveBg = true;
2996                        break;
2997                    }
2998                }
2999
3000                if (!haveBg) {
3001                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3002                    long now = SystemClock.uptimeMillis();
3003                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
3004                        ProcessRecord rec = mLruProcesses.get(i);
3005                        if (rec != app && rec.thread != null &&
3006                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3007                            // The low memory report is overriding any current
3008                            // state for a GC request.  Make sure to do
3009                            // heavy/important/visible/foreground processes first.
3010                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3011                                rec.lastRequestedGc = 0;
3012                            } else {
3013                                rec.lastRequestedGc = rec.lastLowMemory;
3014                            }
3015                            rec.reportLowMemory = true;
3016                            rec.lastLowMemory = now;
3017                            mProcessesToGc.remove(rec);
3018                            addProcessToGcListLocked(rec);
3019                        }
3020                    }
3021                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3022                    scheduleAppGcsLocked();
3023                }
3024            }
3025        } else if (app.pid != pid) {
3026            // A new process has already been started.
3027            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3028                    + ") has died and restarted (pid " + app.pid + ").");
3029            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3030        } else if (DEBUG_PROCESSES) {
3031            Slog.d(TAG, "Received spurious death notification for thread "
3032                    + thread.asBinder());
3033        }
3034    }
3035
3036    /**
3037     * If a stack trace dump file is configured, dump process stack traces.
3038     * @param clearTraces causes the dump file to be erased prior to the new
3039     *    traces being written, if true; when false, the new traces will be
3040     *    appended to any existing file content.
3041     * @param firstPids of dalvik VM processes to dump stack traces for first
3042     * @param lastPids of dalvik VM processes to dump stack traces for last
3043     * @param nativeProcs optional list of native process names to dump stack crawls
3044     * @return file containing stack traces, or null if no dump file is configured
3045     */
3046    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3047            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3048        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3049        if (tracesPath == null || tracesPath.length() == 0) {
3050            return null;
3051        }
3052
3053        File tracesFile = new File(tracesPath);
3054        try {
3055            File tracesDir = tracesFile.getParentFile();
3056            if (!tracesDir.exists()) {
3057                tracesFile.mkdirs();
3058                if (!SELinux.restorecon(tracesDir)) {
3059                    return null;
3060                }
3061            }
3062            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3063
3064            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3065            tracesFile.createNewFile();
3066            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3067        } catch (IOException e) {
3068            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3069            return null;
3070        }
3071
3072        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3073        return tracesFile;
3074    }
3075
3076    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3077            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3078        // Use a FileObserver to detect when traces finish writing.
3079        // The order of traces is considered important to maintain for legibility.
3080        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3081            public synchronized void onEvent(int event, String path) { notify(); }
3082        };
3083
3084        try {
3085            observer.startWatching();
3086
3087            // First collect all of the stacks of the most important pids.
3088            if (firstPids != null) {
3089                try {
3090                    int num = firstPids.size();
3091                    for (int i = 0; i < num; i++) {
3092                        synchronized (observer) {
3093                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3094                            observer.wait(200);  // Wait for write-close, give up after 200msec
3095                        }
3096                    }
3097                } catch (InterruptedException e) {
3098                    Log.wtf(TAG, e);
3099                }
3100            }
3101
3102            // Next measure CPU usage.
3103            if (processStats != null) {
3104                processStats.init();
3105                System.gc();
3106                processStats.update();
3107                try {
3108                    synchronized (processStats) {
3109                        processStats.wait(500); // measure over 1/2 second.
3110                    }
3111                } catch (InterruptedException e) {
3112                }
3113                processStats.update();
3114
3115                // We'll take the stack crawls of just the top apps using CPU.
3116                final int N = processStats.countWorkingStats();
3117                int numProcs = 0;
3118                for (int i=0; i<N && numProcs<5; i++) {
3119                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3120                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3121                        numProcs++;
3122                        try {
3123                            synchronized (observer) {
3124                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3125                                observer.wait(200);  // Wait for write-close, give up after 200msec
3126                            }
3127                        } catch (InterruptedException e) {
3128                            Log.wtf(TAG, e);
3129                        }
3130
3131                    }
3132                }
3133            }
3134
3135        } finally {
3136            observer.stopWatching();
3137        }
3138
3139        if (nativeProcs != null) {
3140            int[] pids = Process.getPidsForCommands(nativeProcs);
3141            if (pids != null) {
3142                for (int pid : pids) {
3143                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3144                }
3145            }
3146        }
3147    }
3148
3149    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3150        if (true || IS_USER_BUILD) {
3151            return;
3152        }
3153        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3154        if (tracesPath == null || tracesPath.length() == 0) {
3155            return;
3156        }
3157
3158        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3159        StrictMode.allowThreadDiskWrites();
3160        try {
3161            final File tracesFile = new File(tracesPath);
3162            final File tracesDir = tracesFile.getParentFile();
3163            final File tracesTmp = new File(tracesDir, "__tmp__");
3164            try {
3165                if (!tracesDir.exists()) {
3166                    tracesFile.mkdirs();
3167                    if (!SELinux.restorecon(tracesDir.getPath())) {
3168                        return;
3169                    }
3170                }
3171                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3172
3173                if (tracesFile.exists()) {
3174                    tracesTmp.delete();
3175                    tracesFile.renameTo(tracesTmp);
3176                }
3177                StringBuilder sb = new StringBuilder();
3178                Time tobj = new Time();
3179                tobj.set(System.currentTimeMillis());
3180                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3181                sb.append(": ");
3182                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3183                sb.append(" since ");
3184                sb.append(msg);
3185                FileOutputStream fos = new FileOutputStream(tracesFile);
3186                fos.write(sb.toString().getBytes());
3187                if (app == null) {
3188                    fos.write("\n*** No application process!".getBytes());
3189                }
3190                fos.close();
3191                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3192            } catch (IOException e) {
3193                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3194                return;
3195            }
3196
3197            if (app != null) {
3198                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3199                firstPids.add(app.pid);
3200                dumpStackTraces(tracesPath, firstPids, null, null, null);
3201            }
3202
3203            File lastTracesFile = null;
3204            File curTracesFile = null;
3205            for (int i=9; i>=0; i--) {
3206                String name = String.format("slow%02d.txt", i);
3207                curTracesFile = new File(tracesDir, name);
3208                if (curTracesFile.exists()) {
3209                    if (lastTracesFile != null) {
3210                        curTracesFile.renameTo(lastTracesFile);
3211                    } else {
3212                        curTracesFile.delete();
3213                    }
3214                }
3215                lastTracesFile = curTracesFile;
3216            }
3217            tracesFile.renameTo(curTracesFile);
3218            if (tracesTmp.exists()) {
3219                tracesTmp.renameTo(tracesFile);
3220            }
3221        } finally {
3222            StrictMode.setThreadPolicy(oldPolicy);
3223        }
3224    }
3225
3226    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3227            ActivityRecord parent, final String annotation) {
3228        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3229        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3230
3231        if (mController != null) {
3232            try {
3233                // 0 == continue, -1 = kill process immediately
3234                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3235                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3236            } catch (RemoteException e) {
3237                mController = null;
3238            }
3239        }
3240
3241        long anrTime = SystemClock.uptimeMillis();
3242        if (MONITOR_CPU_USAGE) {
3243            updateCpuStatsNow();
3244        }
3245
3246        synchronized (this) {
3247            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3248            if (mShuttingDown) {
3249                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3250                return;
3251            } else if (app.notResponding) {
3252                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3253                return;
3254            } else if (app.crashing) {
3255                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3256                return;
3257            }
3258
3259            // In case we come through here for the same app before completing
3260            // this one, mark as anring now so we will bail out.
3261            app.notResponding = true;
3262
3263            // Log the ANR to the event log.
3264            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3265                    annotation);
3266
3267            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3268            firstPids.add(app.pid);
3269
3270            int parentPid = app.pid;
3271            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3272            if (parentPid != app.pid) firstPids.add(parentPid);
3273
3274            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3275
3276            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3277                ProcessRecord r = mLruProcesses.get(i);
3278                if (r != null && r.thread != null) {
3279                    int pid = r.pid;
3280                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3281                        if (r.persistent) {
3282                            firstPids.add(pid);
3283                        } else {
3284                            lastPids.put(pid, Boolean.TRUE);
3285                        }
3286                    }
3287                }
3288            }
3289        }
3290
3291        // Log the ANR to the main log.
3292        StringBuilder info = new StringBuilder();
3293        info.setLength(0);
3294        info.append("ANR in ").append(app.processName);
3295        if (activity != null && activity.shortComponentName != null) {
3296            info.append(" (").append(activity.shortComponentName).append(")");
3297        }
3298        info.append("\n");
3299        if (annotation != null) {
3300            info.append("Reason: ").append(annotation).append("\n");
3301        }
3302        if (parent != null && parent != activity) {
3303            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3304        }
3305
3306        final ProcessStats processStats = new ProcessStats(true);
3307
3308        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3309
3310        String cpuInfo = null;
3311        if (MONITOR_CPU_USAGE) {
3312            updateCpuStatsNow();
3313            synchronized (mProcessStatsThread) {
3314                cpuInfo = mProcessStats.printCurrentState(anrTime);
3315            }
3316            info.append(processStats.printCurrentLoad());
3317            info.append(cpuInfo);
3318        }
3319
3320        info.append(processStats.printCurrentState(anrTime));
3321
3322        Slog.e(TAG, info.toString());
3323        if (tracesFile == null) {
3324            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3325            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3326        }
3327
3328        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3329                cpuInfo, tracesFile, null);
3330
3331        if (mController != null) {
3332            try {
3333                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3334                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3335                if (res != 0) {
3336                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3337                    return;
3338                }
3339            } catch (RemoteException e) {
3340                mController = null;
3341            }
3342        }
3343
3344        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3345        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3346                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3347
3348        synchronized (this) {
3349            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3350                Slog.w(TAG, "Killing " + app + ": background ANR");
3351                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3352                        app.processName, app.setAdj, "background ANR");
3353                Process.killProcessQuiet(app.pid);
3354                return;
3355            }
3356
3357            // Set the app's notResponding state, and look up the errorReportReceiver
3358            makeAppNotRespondingLocked(app,
3359                    activity != null ? activity.shortComponentName : null,
3360                    annotation != null ? "ANR " + annotation : "ANR",
3361                    info.toString());
3362
3363            // Bring up the infamous App Not Responding dialog
3364            Message msg = Message.obtain();
3365            HashMap map = new HashMap();
3366            msg.what = SHOW_NOT_RESPONDING_MSG;
3367            msg.obj = map;
3368            map.put("app", app);
3369            if (activity != null) {
3370                map.put("activity", activity);
3371            }
3372
3373            mHandler.sendMessage(msg);
3374        }
3375    }
3376
3377    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3378        if (!mLaunchWarningShown) {
3379            mLaunchWarningShown = true;
3380            mHandler.post(new Runnable() {
3381                @Override
3382                public void run() {
3383                    synchronized (ActivityManagerService.this) {
3384                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3385                        d.show();
3386                        mHandler.postDelayed(new Runnable() {
3387                            @Override
3388                            public void run() {
3389                                synchronized (ActivityManagerService.this) {
3390                                    d.dismiss();
3391                                    mLaunchWarningShown = false;
3392                                }
3393                            }
3394                        }, 4000);
3395                    }
3396                }
3397            });
3398        }
3399    }
3400
3401    public boolean clearApplicationUserData(final String packageName,
3402            final IPackageDataObserver observer, final int userId) {
3403        enforceNotIsolatedCaller("clearApplicationUserData");
3404        int uid = Binder.getCallingUid();
3405        int pid = Binder.getCallingPid();
3406        long callingId = Binder.clearCallingIdentity();
3407        try {
3408            IPackageManager pm = AppGlobals.getPackageManager();
3409            int pkgUid = -1;
3410            synchronized(this) {
3411                try {
3412                    pkgUid = pm.getPackageUid(packageName, userId);
3413                } catch (RemoteException e) {
3414                }
3415                if (pkgUid == -1) {
3416                    Slog.w(TAG, "Invalid packageName:" + packageName);
3417                    return false;
3418                }
3419                if (uid == pkgUid || checkComponentPermission(
3420                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3421                        pid, uid, -1, true)
3422                        == PackageManager.PERMISSION_GRANTED) {
3423                    forceStopPackageLocked(packageName, pkgUid);
3424                } else {
3425                    throw new SecurityException(pid+" does not have permission:"+
3426                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3427                                    "for process:"+packageName);
3428                }
3429            }
3430
3431            try {
3432                //clear application user data
3433                pm.clearApplicationUserData(packageName, observer, userId);
3434                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3435                        Uri.fromParts("package", packageName, null));
3436                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3437                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3438                        null, null, 0, null, null, null, false, false, userId);
3439            } catch (RemoteException e) {
3440            }
3441        } finally {
3442            Binder.restoreCallingIdentity(callingId);
3443        }
3444        return true;
3445    }
3446
3447    public void killBackgroundProcesses(final String packageName) {
3448        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3449                != PackageManager.PERMISSION_GRANTED &&
3450                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3451                        != PackageManager.PERMISSION_GRANTED) {
3452            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3453                    + Binder.getCallingPid()
3454                    + ", uid=" + Binder.getCallingUid()
3455                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3456            Slog.w(TAG, msg);
3457            throw new SecurityException(msg);
3458        }
3459
3460        int userId = UserHandle.getCallingUserId();
3461        long callingId = Binder.clearCallingIdentity();
3462        try {
3463            IPackageManager pm = AppGlobals.getPackageManager();
3464            int pkgUid = -1;
3465            synchronized(this) {
3466                try {
3467                    pkgUid = pm.getPackageUid(packageName, userId);
3468                } catch (RemoteException e) {
3469                }
3470                if (pkgUid == -1) {
3471                    Slog.w(TAG, "Invalid packageName: " + packageName);
3472                    return;
3473                }
3474                killPackageProcessesLocked(packageName, pkgUid, -1,
3475                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3476            }
3477        } finally {
3478            Binder.restoreCallingIdentity(callingId);
3479        }
3480    }
3481
3482    public void killAllBackgroundProcesses() {
3483        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3484                != PackageManager.PERMISSION_GRANTED) {
3485            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3486                    + Binder.getCallingPid()
3487                    + ", uid=" + Binder.getCallingUid()
3488                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3489            Slog.w(TAG, msg);
3490            throw new SecurityException(msg);
3491        }
3492
3493        long callingId = Binder.clearCallingIdentity();
3494        try {
3495            synchronized(this) {
3496                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3497                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3498                    final int NA = apps.size();
3499                    for (int ia=0; ia<NA; ia++) {
3500                        ProcessRecord app = apps.valueAt(ia);
3501                        if (app.persistent) {
3502                            // we don't kill persistent processes
3503                            continue;
3504                        }
3505                        if (app.removed) {
3506                            procs.add(app);
3507                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3508                            app.removed = true;
3509                            procs.add(app);
3510                        }
3511                    }
3512                }
3513
3514                int N = procs.size();
3515                for (int i=0; i<N; i++) {
3516                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3517                }
3518            }
3519        } finally {
3520            Binder.restoreCallingIdentity(callingId);
3521        }
3522    }
3523
3524    public void forceStopPackage(final String packageName) {
3525        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3526                != PackageManager.PERMISSION_GRANTED) {
3527            String msg = "Permission Denial: forceStopPackage() from pid="
3528                    + Binder.getCallingPid()
3529                    + ", uid=" + Binder.getCallingUid()
3530                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3531            Slog.w(TAG, msg);
3532            throw new SecurityException(msg);
3533        }
3534        final int userId = UserHandle.getCallingUserId();
3535        long callingId = Binder.clearCallingIdentity();
3536        try {
3537            IPackageManager pm = AppGlobals.getPackageManager();
3538            int pkgUid = -1;
3539            synchronized(this) {
3540                try {
3541                    pkgUid = pm.getPackageUid(packageName, userId);
3542                } catch (RemoteException e) {
3543                }
3544                if (pkgUid == -1) {
3545                    Slog.w(TAG, "Invalid packageName: " + packageName);
3546                    return;
3547                }
3548                forceStopPackageLocked(packageName, pkgUid);
3549                try {
3550                    pm.setPackageStoppedState(packageName, true, userId);
3551                } catch (RemoteException e) {
3552                } catch (IllegalArgumentException e) {
3553                    Slog.w(TAG, "Failed trying to unstop package "
3554                            + packageName + ": " + e);
3555                }
3556            }
3557        } finally {
3558            Binder.restoreCallingIdentity(callingId);
3559        }
3560    }
3561
3562    /*
3563     * The pkg name and uid have to be specified.
3564     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3565     */
3566    public void killApplicationWithUid(String pkg, int uid) {
3567        if (pkg == null) {
3568            return;
3569        }
3570        // Make sure the uid is valid.
3571        if (uid < 0) {
3572            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3573            return;
3574        }
3575        int callerUid = Binder.getCallingUid();
3576        // Only the system server can kill an application
3577        if (callerUid == Process.SYSTEM_UID) {
3578            // Post an aysnc message to kill the application
3579            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3580            msg.arg1 = uid;
3581            msg.arg2 = 0;
3582            msg.obj = pkg;
3583            mHandler.sendMessage(msg);
3584        } else {
3585            throw new SecurityException(callerUid + " cannot kill pkg: " +
3586                    pkg);
3587        }
3588    }
3589
3590    public void closeSystemDialogs(String reason) {
3591        enforceNotIsolatedCaller("closeSystemDialogs");
3592
3593        final int uid = Binder.getCallingUid();
3594        final long origId = Binder.clearCallingIdentity();
3595        synchronized (this) {
3596            closeSystemDialogsLocked(uid, reason);
3597        }
3598        Binder.restoreCallingIdentity(origId);
3599    }
3600
3601    void closeSystemDialogsLocked(int callingUid, String reason) {
3602        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3603        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3604        if (reason != null) {
3605            intent.putExtra("reason", reason);
3606        }
3607        mWindowManager.closeSystemDialogs(reason);
3608
3609        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3610            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3611            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3612                r.stack.finishActivityLocked(r, i,
3613                        Activity.RESULT_CANCELED, null, "close-sys");
3614            }
3615        }
3616
3617        broadcastIntentLocked(null, null, intent, null,
3618                null, 0, null, null, null, false, false, -1,
3619                callingUid, 0 /* TODO: Verify */);
3620    }
3621
3622    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3623            throws RemoteException {
3624        enforceNotIsolatedCaller("getProcessMemoryInfo");
3625        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3626        for (int i=pids.length-1; i>=0; i--) {
3627            infos[i] = new Debug.MemoryInfo();
3628            Debug.getMemoryInfo(pids[i], infos[i]);
3629        }
3630        return infos;
3631    }
3632
3633    public long[] getProcessPss(int[] pids) throws RemoteException {
3634        enforceNotIsolatedCaller("getProcessPss");
3635        long[] pss = new long[pids.length];
3636        for (int i=pids.length-1; i>=0; i--) {
3637            pss[i] = Debug.getPss(pids[i]);
3638        }
3639        return pss;
3640    }
3641
3642    public void killApplicationProcess(String processName, int uid) {
3643        if (processName == null) {
3644            return;
3645        }
3646
3647        int callerUid = Binder.getCallingUid();
3648        // Only the system server can kill an application
3649        if (callerUid == Process.SYSTEM_UID) {
3650            synchronized (this) {
3651                ProcessRecord app = getProcessRecordLocked(processName, uid);
3652                if (app != null && app.thread != null) {
3653                    try {
3654                        app.thread.scheduleSuicide();
3655                    } catch (RemoteException e) {
3656                        // If the other end already died, then our work here is done.
3657                    }
3658                } else {
3659                    Slog.w(TAG, "Process/uid not found attempting kill of "
3660                            + processName + " / " + uid);
3661                }
3662            }
3663        } else {
3664            throw new SecurityException(callerUid + " cannot kill app process: " +
3665                    processName);
3666        }
3667    }
3668
3669    private void forceStopPackageLocked(final String packageName, int uid) {
3670        forceStopPackageLocked(packageName, uid, false, false, true, false,
3671                UserHandle.getUserId(uid));
3672        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3673                Uri.fromParts("package", packageName, null));
3674        if (!mProcessesReady) {
3675            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3676        }
3677        intent.putExtra(Intent.EXTRA_UID, uid);
3678        broadcastIntentLocked(null, null, intent,
3679                null, null, 0, null, null, null,
3680                false, false,
3681                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3682    }
3683
3684    private void forceStopUserLocked(int userId) {
3685        forceStopPackageLocked(null, -1, false, false, true, false, userId);
3686        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3687        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3688        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3689        broadcastIntentLocked(null, null, intent,
3690                null, null, 0, null, null, null,
3691                false, false,
3692                MY_PID, Process.SYSTEM_UID, userId);
3693    }
3694
3695    private final boolean killPackageProcessesLocked(String packageName, int uid,
3696            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3697            boolean doit, boolean evenPersistent, String reason) {
3698        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3699
3700        // Remove all processes this package may have touched: all with the
3701        // same UID (except for the system or root user), and all whose name
3702        // matches the package name.
3703        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3704        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3705            final int NA = apps.size();
3706            for (int ia=0; ia<NA; ia++) {
3707                ProcessRecord app = apps.valueAt(ia);
3708                if (app.persistent && !evenPersistent) {
3709                    // we don't kill persistent processes
3710                    continue;
3711                }
3712                if (app.removed) {
3713                    if (doit) {
3714                        procs.add(app);
3715                    }
3716                // If no package is specified, we call all processes under the
3717                // give user id.
3718                } else if (packageName == null) {
3719                    if (app.userId == userId) {
3720                        if (app.setAdj >= minOomAdj) {
3721                            if (!doit) {
3722                                return true;
3723                            }
3724                            app.removed = true;
3725                            procs.add(app);
3726                        }
3727                    }
3728                // If uid is specified and the uid and process name match
3729                // Or, the uid is not specified and the process name matches
3730                } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3731                            || ((app.processName.equals(packageName)
3732                                 || app.processName.startsWith(procNamePrefix))
3733                                && uid < 0))) {
3734                    if (app.setAdj >= minOomAdj) {
3735                        if (!doit) {
3736                            return true;
3737                        }
3738                        app.removed = true;
3739                        procs.add(app);
3740                    }
3741                }
3742            }
3743        }
3744
3745        int N = procs.size();
3746        for (int i=0; i<N; i++) {
3747            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3748        }
3749        return N > 0;
3750    }
3751
3752    private final boolean forceStopPackageLocked(String name, int uid,
3753            boolean callerWillRestart, boolean purgeCache, boolean doit,
3754            boolean evenPersistent, int userId) {
3755        int i;
3756        int N;
3757
3758        if (uid < 0 && name != null) {
3759            try {
3760                uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
3761            } catch (RemoteException e) {
3762            }
3763        }
3764
3765        if (doit) {
3766            if (name != null) {
3767                Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3768            } else {
3769                Slog.i(TAG, "Force stopping user " + userId);
3770            }
3771
3772            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3773            while (badApps.hasNext()) {
3774                SparseArray<Long> ba = badApps.next();
3775                for (i=ba.size()-1; i>=0; i--) {
3776                    boolean remove = false;
3777                    final int entUid = ba.keyAt(i);
3778                    if (name != null) {
3779                        if (entUid == uid) {
3780                            remove = true;
3781                        }
3782                    } else if (UserHandle.getUserId(entUid) == userId) {
3783                        remove = true;
3784                    }
3785                    if (remove) {
3786                        ba.removeAt(i);
3787                    }
3788                }
3789                if (ba.size() == 0) {
3790                    badApps.remove();
3791                }
3792            }
3793        }
3794
3795        boolean didSomething = killPackageProcessesLocked(name, uid,
3796                name == null ? userId : -1 , -100, callerWillRestart, false,
3797                doit, evenPersistent,
3798                name == null ? ("force stop user " + userId) : ("force stop " + name));
3799
3800        TaskRecord lastTask = null;
3801        for (i=0; i<mMainStack.mHistory.size(); i++) {
3802            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3803            final boolean samePackage = r.packageName.equals(name)
3804                    || (name == null && r.userId == userId);
3805            if (r.userId == userId
3806                    && (samePackage || r.task == lastTask)
3807                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3808                if (!doit) {
3809                    if (r.finishing) {
3810                        // If this activity is just finishing, then it is not
3811                        // interesting as far as something to stop.
3812                        continue;
3813                    }
3814                    return true;
3815                }
3816                didSomething = true;
3817                Slog.i(TAG, "  Force finishing activity " + r);
3818                if (samePackage) {
3819                    if (r.app != null) {
3820                        r.app.removed = true;
3821                    }
3822                    r.app = null;
3823                }
3824                lastTask = r.task;
3825                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3826                        null, "force-stop", true)) {
3827                    i--;
3828                }
3829            }
3830        }
3831
3832        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3833            if (!doit) {
3834                return true;
3835            }
3836            didSomething = true;
3837        }
3838
3839        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3840        for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
3841            if ((name == null || provider.info.packageName.equals(name))
3842                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3843                if (!doit) {
3844                    return true;
3845                }
3846                didSomething = true;
3847                providers.add(provider);
3848            }
3849        }
3850
3851        N = providers.size();
3852        for (i=0; i<N; i++) {
3853            removeDyingProviderLocked(null, providers.get(i), true);
3854        }
3855
3856        if (doit) {
3857            if (purgeCache && name != null) {
3858                AttributeCache ac = AttributeCache.instance();
3859                if (ac != null) {
3860                    ac.removePackage(name);
3861                }
3862            }
3863            if (mBooted) {
3864                mMainStack.resumeTopActivityLocked(null);
3865                mMainStack.scheduleIdleLocked();
3866            }
3867        }
3868
3869        return didSomething;
3870    }
3871
3872    private final boolean removeProcessLocked(ProcessRecord app,
3873            boolean callerWillRestart, boolean allowRestart, String reason) {
3874        final String name = app.processName;
3875        final int uid = app.uid;
3876        if (DEBUG_PROCESSES) Slog.d(
3877            TAG, "Force removing proc " + app.toShortString() + " (" + name
3878            + "/" + uid + ")");
3879
3880        mProcessNames.remove(name, uid);
3881        mIsolatedProcesses.remove(app.uid);
3882        if (mHeavyWeightProcess == app) {
3883            mHeavyWeightProcess = null;
3884            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3885        }
3886        boolean needRestart = false;
3887        if (app.pid > 0 && app.pid != MY_PID) {
3888            int pid = app.pid;
3889            synchronized (mPidsSelfLocked) {
3890                mPidsSelfLocked.remove(pid);
3891                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3892            }
3893            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3894            handleAppDiedLocked(app, true, allowRestart);
3895            mLruProcesses.remove(app);
3896            Process.killProcessQuiet(pid);
3897
3898            if (app.persistent && !app.isolated) {
3899                if (!callerWillRestart) {
3900                    addAppLocked(app.info, false);
3901                } else {
3902                    needRestart = true;
3903                }
3904            }
3905        } else {
3906            mRemovedProcesses.add(app);
3907        }
3908
3909        return needRestart;
3910    }
3911
3912    private final void processStartTimedOutLocked(ProcessRecord app) {
3913        final int pid = app.pid;
3914        boolean gone = false;
3915        synchronized (mPidsSelfLocked) {
3916            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3917            if (knownApp != null && knownApp.thread == null) {
3918                mPidsSelfLocked.remove(pid);
3919                gone = true;
3920            }
3921        }
3922
3923        if (gone) {
3924            Slog.w(TAG, "Process " + app + " failed to attach");
3925            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
3926                    app.processName);
3927            mProcessNames.remove(app.processName, app.uid);
3928            mIsolatedProcesses.remove(app.uid);
3929            if (mHeavyWeightProcess == app) {
3930                mHeavyWeightProcess = null;
3931                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3932            }
3933            // Take care of any launching providers waiting for this process.
3934            checkAppInLaunchingProvidersLocked(app, true);
3935            // Take care of any services that are waiting for the process.
3936            mServices.processStartTimedOutLocked(app);
3937            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3938                    app.processName, app.setAdj, "start timeout");
3939            Process.killProcessQuiet(pid);
3940            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3941                Slog.w(TAG, "Unattached app died before backup, skipping");
3942                try {
3943                    IBackupManager bm = IBackupManager.Stub.asInterface(
3944                            ServiceManager.getService(Context.BACKUP_SERVICE));
3945                    bm.agentDisconnected(app.info.packageName);
3946                } catch (RemoteException e) {
3947                    // Can't happen; the backup manager is local
3948                }
3949            }
3950            if (isPendingBroadcastProcessLocked(pid)) {
3951                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3952                skipPendingBroadcastLocked(pid);
3953            }
3954        } else {
3955            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3956        }
3957    }
3958
3959    private final boolean attachApplicationLocked(IApplicationThread thread,
3960            int pid) {
3961
3962        // Find the application record that is being attached...  either via
3963        // the pid if we are running in multiple processes, or just pull the
3964        // next app record if we are emulating process with anonymous threads.
3965        ProcessRecord app;
3966        if (pid != MY_PID && pid >= 0) {
3967            synchronized (mPidsSelfLocked) {
3968                app = mPidsSelfLocked.get(pid);
3969            }
3970        } else {
3971            app = null;
3972        }
3973
3974        if (app == null) {
3975            Slog.w(TAG, "No pending application record for pid " + pid
3976                    + " (IApplicationThread " + thread + "); dropping process");
3977            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3978            if (pid > 0 && pid != MY_PID) {
3979                Process.killProcessQuiet(pid);
3980            } else {
3981                try {
3982                    thread.scheduleExit();
3983                } catch (Exception e) {
3984                    // Ignore exceptions.
3985                }
3986            }
3987            return false;
3988        }
3989
3990        // If this application record is still attached to a previous
3991        // process, clean it up now.
3992        if (app.thread != null) {
3993            handleAppDiedLocked(app, true, true);
3994        }
3995
3996        // Tell the process all about itself.
3997
3998        if (localLOGV) Slog.v(
3999                TAG, "Binding process pid " + pid + " to record " + app);
4000
4001        String processName = app.processName;
4002        try {
4003            AppDeathRecipient adr = new AppDeathRecipient(
4004                    app, pid, thread);
4005            thread.asBinder().linkToDeath(adr, 0);
4006            app.deathRecipient = adr;
4007        } catch (RemoteException e) {
4008            app.resetPackageList();
4009            startProcessLocked(app, "link fail", processName);
4010            return false;
4011        }
4012
4013        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
4014
4015        app.thread = thread;
4016        app.curAdj = app.setAdj = -100;
4017        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4018        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4019        app.forcingToForeground = null;
4020        app.foregroundServices = false;
4021        app.hasShownUi = false;
4022        app.debugging = false;
4023
4024        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4025
4026        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4027        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4028
4029        if (!normalMode) {
4030            Slog.i(TAG, "Launching preboot mode app: " + app);
4031        }
4032
4033        if (localLOGV) Slog.v(
4034            TAG, "New app record " + app
4035            + " thread=" + thread.asBinder() + " pid=" + pid);
4036        try {
4037            int testMode = IApplicationThread.DEBUG_OFF;
4038            if (mDebugApp != null && mDebugApp.equals(processName)) {
4039                testMode = mWaitForDebugger
4040                    ? IApplicationThread.DEBUG_WAIT
4041                    : IApplicationThread.DEBUG_ON;
4042                app.debugging = true;
4043                if (mDebugTransient) {
4044                    mDebugApp = mOrigDebugApp;
4045                    mWaitForDebugger = mOrigWaitForDebugger;
4046                }
4047            }
4048            String profileFile = app.instrumentationProfileFile;
4049            ParcelFileDescriptor profileFd = null;
4050            boolean profileAutoStop = false;
4051            if (mProfileApp != null && mProfileApp.equals(processName)) {
4052                mProfileProc = app;
4053                profileFile = mProfileFile;
4054                profileFd = mProfileFd;
4055                profileAutoStop = mAutoStopProfiler;
4056            }
4057            boolean enableOpenGlTrace = false;
4058            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4059                enableOpenGlTrace = true;
4060                mOpenGlTraceApp = null;
4061            }
4062
4063            // If the app is being launched for restore or full backup, set it up specially
4064            boolean isRestrictedBackupMode = false;
4065            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4066                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4067                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4068                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4069            }
4070
4071            ensurePackageDexOpt(app.instrumentationInfo != null
4072                    ? app.instrumentationInfo.packageName
4073                    : app.info.packageName);
4074            if (app.instrumentationClass != null) {
4075                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4076            }
4077            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4078                    + processName + " with config " + mConfiguration);
4079            ApplicationInfo appInfo = app.instrumentationInfo != null
4080                    ? app.instrumentationInfo : app.info;
4081            app.compat = compatibilityInfoForPackageLocked(appInfo);
4082            if (profileFd != null) {
4083                profileFd = profileFd.dup();
4084            }
4085            thread.bindApplication(processName, appInfo, providers,
4086                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4087                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4088                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4089                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4090                    mCoreSettingsObserver.getCoreSettingsLocked());
4091            updateLruProcessLocked(app, false, true);
4092            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4093        } catch (Exception e) {
4094            // todo: Yikes!  What should we do?  For now we will try to
4095            // start another process, but that could easily get us in
4096            // an infinite loop of restarting processes...
4097            Slog.w(TAG, "Exception thrown during bind!", e);
4098
4099            app.resetPackageList();
4100            app.unlinkDeathRecipient();
4101            startProcessLocked(app, "bind fail", processName);
4102            return false;
4103        }
4104
4105        // Remove this record from the list of starting applications.
4106        mPersistentStartingProcesses.remove(app);
4107        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4108                "Attach application locked removing on hold: " + app);
4109        mProcessesOnHold.remove(app);
4110
4111        boolean badApp = false;
4112        boolean didSomething = false;
4113
4114        // See if the top visible activity is waiting to run in this process...
4115        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4116        if (hr != null && normalMode) {
4117            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4118                    && processName.equals(hr.processName)) {
4119                try {
4120                    if (mHeadless) {
4121                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4122                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4123                        didSomething = true;
4124                    }
4125                } catch (Exception e) {
4126                    Slog.w(TAG, "Exception in new application when starting activity "
4127                          + hr.intent.getComponent().flattenToShortString(), e);
4128                    badApp = true;
4129                }
4130            } else {
4131                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4132            }
4133        }
4134
4135        // Find any services that should be running in this process...
4136        if (!badApp) {
4137            try {
4138                didSomething |= mServices.attachApplicationLocked(app, processName);
4139            } catch (Exception e) {
4140                badApp = true;
4141            }
4142        }
4143
4144        // Check if a next-broadcast receiver is in this process...
4145        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4146            try {
4147                didSomething = sendPendingBroadcastsLocked(app);
4148            } catch (Exception e) {
4149                // If the app died trying to launch the receiver we declare it 'bad'
4150                badApp = true;
4151            }
4152        }
4153
4154        // Check whether the next backup agent is in this process...
4155        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4156            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4157            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4158            try {
4159                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4160                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4161                        mBackupTarget.backupMode);
4162            } catch (Exception e) {
4163                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4164                e.printStackTrace();
4165            }
4166        }
4167
4168        if (badApp) {
4169            // todo: Also need to kill application to deal with all
4170            // kinds of exceptions.
4171            handleAppDiedLocked(app, false, true);
4172            return false;
4173        }
4174
4175        if (!didSomething) {
4176            updateOomAdjLocked();
4177        }
4178
4179        return true;
4180    }
4181
4182    public final void attachApplication(IApplicationThread thread) {
4183        synchronized (this) {
4184            int callingPid = Binder.getCallingPid();
4185            final long origId = Binder.clearCallingIdentity();
4186            attachApplicationLocked(thread, callingPid);
4187            Binder.restoreCallingIdentity(origId);
4188        }
4189    }
4190
4191    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4192        final long origId = Binder.clearCallingIdentity();
4193        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4194        if (stopProfiling) {
4195            synchronized (this) {
4196                if (mProfileProc == r.app) {
4197                    if (mProfileFd != null) {
4198                        try {
4199                            mProfileFd.close();
4200                        } catch (IOException e) {
4201                        }
4202                        clearProfilerLocked();
4203                    }
4204                }
4205            }
4206        }
4207        Binder.restoreCallingIdentity(origId);
4208    }
4209
4210    void enableScreenAfterBoot() {
4211        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4212                SystemClock.uptimeMillis());
4213        mWindowManager.enableScreenAfterBoot();
4214
4215        synchronized (this) {
4216            updateEventDispatchingLocked();
4217        }
4218    }
4219
4220    public void showBootMessage(final CharSequence msg, final boolean always) {
4221        enforceNotIsolatedCaller("showBootMessage");
4222        mWindowManager.showBootMessage(msg, always);
4223    }
4224
4225    public void dismissKeyguardOnNextActivity() {
4226        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4227        final long token = Binder.clearCallingIdentity();
4228        try {
4229            synchronized (this) {
4230                if (mLockScreenShown) {
4231                    mLockScreenShown = false;
4232                    comeOutOfSleepIfNeededLocked();
4233                }
4234                mMainStack.dismissKeyguardOnNextActivityLocked();
4235            }
4236        } finally {
4237            Binder.restoreCallingIdentity(token);
4238        }
4239    }
4240
4241    final void finishBooting() {
4242        IntentFilter pkgFilter = new IntentFilter();
4243        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4244        pkgFilter.addDataScheme("package");
4245        mContext.registerReceiver(new BroadcastReceiver() {
4246            @Override
4247            public void onReceive(Context context, Intent intent) {
4248                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4249                if (pkgs != null) {
4250                    for (String pkg : pkgs) {
4251                        synchronized (ActivityManagerService.this) {
4252                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4253                                setResultCode(Activity.RESULT_OK);
4254                                return;
4255                            }
4256                        }
4257                    }
4258                }
4259            }
4260        }, pkgFilter);
4261
4262        synchronized (this) {
4263            // Ensure that any processes we had put on hold are now started
4264            // up.
4265            final int NP = mProcessesOnHold.size();
4266            if (NP > 0) {
4267                ArrayList<ProcessRecord> procs =
4268                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4269                for (int ip=0; ip<NP; ip++) {
4270                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4271                            + procs.get(ip));
4272                    startProcessLocked(procs.get(ip), "on-hold", null);
4273                }
4274            }
4275
4276            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4277                // Start looking for apps that are abusing wake locks.
4278                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4279                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4280                // Tell anyone interested that we are done booting!
4281                SystemProperties.set("sys.boot_completed", "1");
4282                SystemProperties.set("dev.bootcomplete", "1");
4283                for (int i=0; i<mStartedUsers.size(); i++) {
4284                    UserStartedState uss = mStartedUsers.valueAt(i);
4285                    if (uss.mState == UserStartedState.STATE_BOOTING) {
4286                        uss.mState = UserStartedState.STATE_RUNNING;
4287                        broadcastIntentLocked(null, null,
4288                                new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4289                                null, null, 0, null, null,
4290                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4291                                false, false, MY_PID, Process.SYSTEM_UID,
4292                                mStartedUsers.keyAt(i));
4293                    }
4294                }
4295            }
4296        }
4297    }
4298
4299    final void ensureBootCompleted() {
4300        boolean booting;
4301        boolean enableScreen;
4302        synchronized (this) {
4303            booting = mBooting;
4304            mBooting = false;
4305            enableScreen = !mBooted;
4306            mBooted = true;
4307        }
4308
4309        if (booting) {
4310            finishBooting();
4311        }
4312
4313        if (enableScreen) {
4314            enableScreenAfterBoot();
4315        }
4316    }
4317
4318    public final void activityPaused(IBinder token) {
4319        final long origId = Binder.clearCallingIdentity();
4320        mMainStack.activityPaused(token, false);
4321        Binder.restoreCallingIdentity(origId);
4322    }
4323
4324    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4325            CharSequence description) {
4326        if (localLOGV) Slog.v(
4327            TAG, "Activity stopped: token=" + token);
4328
4329        // Refuse possible leaked file descriptors
4330        if (icicle != null && icicle.hasFileDescriptors()) {
4331            throw new IllegalArgumentException("File descriptors passed in Bundle");
4332        }
4333
4334        ActivityRecord r = null;
4335
4336        final long origId = Binder.clearCallingIdentity();
4337
4338        synchronized (this) {
4339            r = mMainStack.isInStackLocked(token);
4340            if (r != null) {
4341                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4342            }
4343        }
4344
4345        if (r != null) {
4346            sendPendingThumbnail(r, null, null, null, false);
4347        }
4348
4349        trimApplications();
4350
4351        Binder.restoreCallingIdentity(origId);
4352    }
4353
4354    public final void activityDestroyed(IBinder token) {
4355        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4356        mMainStack.activityDestroyed(token);
4357    }
4358
4359    public String getCallingPackage(IBinder token) {
4360        synchronized (this) {
4361            ActivityRecord r = getCallingRecordLocked(token);
4362            return r != null && r.app != null ? r.info.packageName : null;
4363        }
4364    }
4365
4366    public ComponentName getCallingActivity(IBinder token) {
4367        synchronized (this) {
4368            ActivityRecord r = getCallingRecordLocked(token);
4369            return r != null ? r.intent.getComponent() : null;
4370        }
4371    }
4372
4373    private ActivityRecord getCallingRecordLocked(IBinder token) {
4374        ActivityRecord r = mMainStack.isInStackLocked(token);
4375        if (r == null) {
4376            return null;
4377        }
4378        return r.resultTo;
4379    }
4380
4381    public ComponentName getActivityClassForToken(IBinder token) {
4382        synchronized(this) {
4383            ActivityRecord r = mMainStack.isInStackLocked(token);
4384            if (r == null) {
4385                return null;
4386            }
4387            return r.intent.getComponent();
4388        }
4389    }
4390
4391    public String getPackageForToken(IBinder token) {
4392        synchronized(this) {
4393            ActivityRecord r = mMainStack.isInStackLocked(token);
4394            if (r == null) {
4395                return null;
4396            }
4397            return r.packageName;
4398        }
4399    }
4400
4401    public IIntentSender getIntentSender(int type,
4402            String packageName, IBinder token, String resultWho,
4403            int requestCode, Intent[] intents, String[] resolvedTypes,
4404            int flags, Bundle options) {
4405        enforceNotIsolatedCaller("getIntentSender");
4406        // Refuse possible leaked file descriptors
4407        if (intents != null) {
4408            if (intents.length < 1) {
4409                throw new IllegalArgumentException("Intents array length must be >= 1");
4410            }
4411            for (int i=0; i<intents.length; i++) {
4412                Intent intent = intents[i];
4413                if (intent != null) {
4414                    if (intent.hasFileDescriptors()) {
4415                        throw new IllegalArgumentException("File descriptors passed in Intent");
4416                    }
4417                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4418                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4419                        throw new IllegalArgumentException(
4420                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4421                    }
4422                    intents[i] = new Intent(intent);
4423                }
4424            }
4425            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4426                throw new IllegalArgumentException(
4427                        "Intent array length does not match resolvedTypes length");
4428            }
4429        }
4430        if (options != null) {
4431            if (options.hasFileDescriptors()) {
4432                throw new IllegalArgumentException("File descriptors passed in options");
4433            }
4434        }
4435
4436        synchronized(this) {
4437            int callingUid = Binder.getCallingUid();
4438            try {
4439                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4440                    int uid = AppGlobals.getPackageManager()
4441                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4442                    if (!UserHandle.isSameApp(callingUid, uid)) {
4443                        String msg = "Permission Denial: getIntentSender() from pid="
4444                            + Binder.getCallingPid()
4445                            + ", uid=" + Binder.getCallingUid()
4446                            + ", (need uid=" + uid + ")"
4447                            + " is not allowed to send as package " + packageName;
4448                        Slog.w(TAG, msg);
4449                        throw new SecurityException(msg);
4450                    }
4451                }
4452
4453                if (DEBUG_MU)
4454                    Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
4455                            + Binder.getOrigCallingUid());
4456                return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
4457                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4458
4459            } catch (RemoteException e) {
4460                throw new SecurityException(e);
4461            }
4462        }
4463    }
4464
4465    IIntentSender getIntentSenderLocked(int type,
4466            String packageName, int callingUid, IBinder token, String resultWho,
4467            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4468            Bundle options) {
4469        if (DEBUG_MU)
4470            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4471        ActivityRecord activity = null;
4472        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4473            activity = mMainStack.isInStackLocked(token);
4474            if (activity == null) {
4475                return null;
4476            }
4477            if (activity.finishing) {
4478                return null;
4479            }
4480        }
4481
4482        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4483        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4484        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4485        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4486                |PendingIntent.FLAG_UPDATE_CURRENT);
4487
4488        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4489                type, packageName, activity, resultWho,
4490                requestCode, intents, resolvedTypes, flags, options,
4491                UserHandle.getUserId(callingUid));
4492        WeakReference<PendingIntentRecord> ref;
4493        ref = mIntentSenderRecords.get(key);
4494        PendingIntentRecord rec = ref != null ? ref.get() : null;
4495        if (rec != null) {
4496            if (!cancelCurrent) {
4497                if (updateCurrent) {
4498                    if (rec.key.requestIntent != null) {
4499                        rec.key.requestIntent.replaceExtras(intents != null ?
4500                                intents[intents.length - 1] : null);
4501                    }
4502                    if (intents != null) {
4503                        intents[intents.length-1] = rec.key.requestIntent;
4504                        rec.key.allIntents = intents;
4505                        rec.key.allResolvedTypes = resolvedTypes;
4506                    } else {
4507                        rec.key.allIntents = null;
4508                        rec.key.allResolvedTypes = null;
4509                    }
4510                }
4511                return rec;
4512            }
4513            rec.canceled = true;
4514            mIntentSenderRecords.remove(key);
4515        }
4516        if (noCreate) {
4517            return rec;
4518        }
4519        rec = new PendingIntentRecord(this, key, callingUid);
4520        mIntentSenderRecords.put(key, rec.ref);
4521        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4522            if (activity.pendingResults == null) {
4523                activity.pendingResults
4524                        = new HashSet<WeakReference<PendingIntentRecord>>();
4525            }
4526            activity.pendingResults.add(rec.ref);
4527        }
4528        return rec;
4529    }
4530
4531    public void cancelIntentSender(IIntentSender sender) {
4532        if (!(sender instanceof PendingIntentRecord)) {
4533            return;
4534        }
4535        synchronized(this) {
4536            PendingIntentRecord rec = (PendingIntentRecord)sender;
4537            try {
4538                int uid = AppGlobals.getPackageManager()
4539                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4540                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4541                    String msg = "Permission Denial: cancelIntentSender() from pid="
4542                        + Binder.getCallingPid()
4543                        + ", uid=" + Binder.getCallingUid()
4544                        + " is not allowed to cancel packges "
4545                        + rec.key.packageName;
4546                    Slog.w(TAG, msg);
4547                    throw new SecurityException(msg);
4548                }
4549            } catch (RemoteException e) {
4550                throw new SecurityException(e);
4551            }
4552            cancelIntentSenderLocked(rec, true);
4553        }
4554    }
4555
4556    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4557        rec.canceled = true;
4558        mIntentSenderRecords.remove(rec.key);
4559        if (cleanActivity && rec.key.activity != null) {
4560            rec.key.activity.pendingResults.remove(rec.ref);
4561        }
4562    }
4563
4564    public String getPackageForIntentSender(IIntentSender pendingResult) {
4565        if (!(pendingResult instanceof PendingIntentRecord)) {
4566            return null;
4567        }
4568        try {
4569            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4570            return res.key.packageName;
4571        } catch (ClassCastException e) {
4572        }
4573        return null;
4574    }
4575
4576    public int getUidForIntentSender(IIntentSender sender) {
4577        if (sender instanceof PendingIntentRecord) {
4578            try {
4579                PendingIntentRecord res = (PendingIntentRecord)sender;
4580                return res.uid;
4581            } catch (ClassCastException e) {
4582            }
4583        }
4584        return -1;
4585    }
4586
4587    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4588        if (!(pendingResult instanceof PendingIntentRecord)) {
4589            return false;
4590        }
4591        try {
4592            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4593            if (res.key.allIntents == null) {
4594                return false;
4595            }
4596            for (int i=0; i<res.key.allIntents.length; i++) {
4597                Intent intent = res.key.allIntents[i];
4598                if (intent.getPackage() != null && intent.getComponent() != null) {
4599                    return false;
4600                }
4601            }
4602            return true;
4603        } catch (ClassCastException e) {
4604        }
4605        return false;
4606    }
4607
4608    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4609        if (!(pendingResult instanceof PendingIntentRecord)) {
4610            return false;
4611        }
4612        try {
4613            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4614            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4615                return true;
4616            }
4617            return false;
4618        } catch (ClassCastException e) {
4619        }
4620        return false;
4621    }
4622
4623    public void setProcessLimit(int max) {
4624        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4625                "setProcessLimit()");
4626        synchronized (this) {
4627            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4628            mProcessLimitOverride = max;
4629        }
4630        trimApplications();
4631    }
4632
4633    public int getProcessLimit() {
4634        synchronized (this) {
4635            return mProcessLimitOverride;
4636        }
4637    }
4638
4639    void foregroundTokenDied(ForegroundToken token) {
4640        synchronized (ActivityManagerService.this) {
4641            synchronized (mPidsSelfLocked) {
4642                ForegroundToken cur
4643                    = mForegroundProcesses.get(token.pid);
4644                if (cur != token) {
4645                    return;
4646                }
4647                mForegroundProcesses.remove(token.pid);
4648                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4649                if (pr == null) {
4650                    return;
4651                }
4652                pr.forcingToForeground = null;
4653                pr.foregroundServices = false;
4654            }
4655            updateOomAdjLocked();
4656        }
4657    }
4658
4659    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4660        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4661                "setProcessForeground()");
4662        synchronized(this) {
4663            boolean changed = false;
4664
4665            synchronized (mPidsSelfLocked) {
4666                ProcessRecord pr = mPidsSelfLocked.get(pid);
4667                if (pr == null && isForeground) {
4668                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4669                    return;
4670                }
4671                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4672                if (oldToken != null) {
4673                    oldToken.token.unlinkToDeath(oldToken, 0);
4674                    mForegroundProcesses.remove(pid);
4675                    if (pr != null) {
4676                        pr.forcingToForeground = null;
4677                    }
4678                    changed = true;
4679                }
4680                if (isForeground && token != null) {
4681                    ForegroundToken newToken = new ForegroundToken() {
4682                        public void binderDied() {
4683                            foregroundTokenDied(this);
4684                        }
4685                    };
4686                    newToken.pid = pid;
4687                    newToken.token = token;
4688                    try {
4689                        token.linkToDeath(newToken, 0);
4690                        mForegroundProcesses.put(pid, newToken);
4691                        pr.forcingToForeground = token;
4692                        changed = true;
4693                    } catch (RemoteException e) {
4694                        // If the process died while doing this, we will later
4695                        // do the cleanup with the process death link.
4696                    }
4697                }
4698            }
4699
4700            if (changed) {
4701                updateOomAdjLocked();
4702            }
4703        }
4704    }
4705
4706    // =========================================================
4707    // PERMISSIONS
4708    // =========================================================
4709
4710    static class PermissionController extends IPermissionController.Stub {
4711        ActivityManagerService mActivityManagerService;
4712        PermissionController(ActivityManagerService activityManagerService) {
4713            mActivityManagerService = activityManagerService;
4714        }
4715
4716        public boolean checkPermission(String permission, int pid, int uid) {
4717            return mActivityManagerService.checkPermission(permission, pid,
4718                    uid) == PackageManager.PERMISSION_GRANTED;
4719        }
4720    }
4721
4722    /**
4723     * This can be called with or without the global lock held.
4724     */
4725    int checkComponentPermission(String permission, int pid, int uid,
4726            int owningUid, boolean exported) {
4727        // We might be performing an operation on behalf of an indirect binder
4728        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4729        // client identity accordingly before proceeding.
4730        Identity tlsIdentity = sCallerIdentity.get();
4731        if (tlsIdentity != null) {
4732            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4733                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4734            uid = tlsIdentity.uid;
4735            pid = tlsIdentity.pid;
4736        }
4737
4738        if (pid == MY_PID) {
4739            return PackageManager.PERMISSION_GRANTED;
4740        }
4741
4742        return ActivityManager.checkComponentPermission(permission, uid,
4743                owningUid, exported);
4744    }
4745
4746    /**
4747     * As the only public entry point for permissions checking, this method
4748     * can enforce the semantic that requesting a check on a null global
4749     * permission is automatically denied.  (Internally a null permission
4750     * string is used when calling {@link #checkComponentPermission} in cases
4751     * when only uid-based security is needed.)
4752     *
4753     * This can be called with or without the global lock held.
4754     */
4755    public int checkPermission(String permission, int pid, int uid) {
4756        if (permission == null) {
4757            return PackageManager.PERMISSION_DENIED;
4758        }
4759        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4760    }
4761
4762    /**
4763     * Binder IPC calls go through the public entry point.
4764     * This can be called with or without the global lock held.
4765     */
4766    int checkCallingPermission(String permission) {
4767        return checkPermission(permission,
4768                Binder.getCallingPid(),
4769                UserHandle.getAppId(Binder.getCallingUid()));
4770    }
4771
4772    /**
4773     * This can be called with or without the global lock held.
4774     */
4775    void enforceCallingPermission(String permission, String func) {
4776        if (checkCallingPermission(permission)
4777                == PackageManager.PERMISSION_GRANTED) {
4778            return;
4779        }
4780
4781        String msg = "Permission Denial: " + func + " from pid="
4782                + Binder.getCallingPid()
4783                + ", uid=" + Binder.getCallingUid()
4784                + " requires " + permission;
4785        Slog.w(TAG, msg);
4786        throw new SecurityException(msg);
4787    }
4788
4789    /**
4790     * Determine if UID is holding permissions required to access {@link Uri} in
4791     * the given {@link ProviderInfo}. Final permission checking is always done
4792     * in {@link ContentProvider}.
4793     */
4794    private final boolean checkHoldingPermissionsLocked(
4795            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4796        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4797                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4798
4799        if (pi.applicationInfo.uid == uid) {
4800            return true;
4801        } else if (!pi.exported) {
4802            return false;
4803        }
4804
4805        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4806        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4807        try {
4808            // check if target holds top-level <provider> permissions
4809            if (!readMet && pi.readPermission != null
4810                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4811                readMet = true;
4812            }
4813            if (!writeMet && pi.writePermission != null
4814                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4815                writeMet = true;
4816            }
4817
4818            // track if unprotected read/write is allowed; any denied
4819            // <path-permission> below removes this ability
4820            boolean allowDefaultRead = pi.readPermission == null;
4821            boolean allowDefaultWrite = pi.writePermission == null;
4822
4823            // check if target holds any <path-permission> that match uri
4824            final PathPermission[] pps = pi.pathPermissions;
4825            if (pps != null) {
4826                final String path = uri.getPath();
4827                int i = pps.length;
4828                while (i > 0 && (!readMet || !writeMet)) {
4829                    i--;
4830                    PathPermission pp = pps[i];
4831                    if (pp.match(path)) {
4832                        if (!readMet) {
4833                            final String pprperm = pp.getReadPermission();
4834                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4835                                    + pprperm + " for " + pp.getPath()
4836                                    + ": match=" + pp.match(path)
4837                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4838                            if (pprperm != null) {
4839                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4840                                    readMet = true;
4841                                } else {
4842                                    allowDefaultRead = false;
4843                                }
4844                            }
4845                        }
4846                        if (!writeMet) {
4847                            final String ppwperm = pp.getWritePermission();
4848                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4849                                    + ppwperm + " for " + pp.getPath()
4850                                    + ": match=" + pp.match(path)
4851                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4852                            if (ppwperm != null) {
4853                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4854                                    writeMet = true;
4855                                } else {
4856                                    allowDefaultWrite = false;
4857                                }
4858                            }
4859                        }
4860                    }
4861                }
4862            }
4863
4864            // grant unprotected <provider> read/write, if not blocked by
4865            // <path-permission> above
4866            if (allowDefaultRead) readMet = true;
4867            if (allowDefaultWrite) writeMet = true;
4868
4869        } catch (RemoteException e) {
4870            return false;
4871        }
4872
4873        return readMet && writeMet;
4874    }
4875
4876    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4877            int modeFlags) {
4878        // Root gets to do everything.
4879        if (uid == 0) {
4880            return true;
4881        }
4882        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4883        if (perms == null) return false;
4884        UriPermission perm = perms.get(uri);
4885        if (perm == null) return false;
4886        return (modeFlags&perm.modeFlags) == modeFlags;
4887    }
4888
4889    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4890        enforceNotIsolatedCaller("checkUriPermission");
4891
4892        // Another redirected-binder-call permissions check as in
4893        // {@link checkComponentPermission}.
4894        Identity tlsIdentity = sCallerIdentity.get();
4895        if (tlsIdentity != null) {
4896            uid = tlsIdentity.uid;
4897            pid = tlsIdentity.pid;
4898        }
4899
4900        uid = UserHandle.getAppId(uid);
4901        // Our own process gets to do everything.
4902        if (pid == MY_PID) {
4903            return PackageManager.PERMISSION_GRANTED;
4904        }
4905        synchronized(this) {
4906            return checkUriPermissionLocked(uri, uid, modeFlags)
4907                    ? PackageManager.PERMISSION_GRANTED
4908                    : PackageManager.PERMISSION_DENIED;
4909        }
4910    }
4911
4912    /**
4913     * Check if the targetPkg can be granted permission to access uri by
4914     * the callingUid using the given modeFlags.  Throws a security exception
4915     * if callingUid is not allowed to do this.  Returns the uid of the target
4916     * if the URI permission grant should be performed; returns -1 if it is not
4917     * needed (for example targetPkg already has permission to access the URI).
4918     * If you already know the uid of the target, you can supply it in
4919     * lastTargetUid else set that to -1.
4920     */
4921    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4922            Uri uri, int modeFlags, int lastTargetUid) {
4923        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4924                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4925        if (modeFlags == 0) {
4926            return -1;
4927        }
4928
4929        if (targetPkg != null) {
4930            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4931                    "Checking grant " + targetPkg + " permission to " + uri);
4932        }
4933
4934        final IPackageManager pm = AppGlobals.getPackageManager();
4935
4936        // If this is not a content: uri, we can't do anything with it.
4937        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4938            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4939                    "Can't grant URI permission for non-content URI: " + uri);
4940            return -1;
4941        }
4942
4943        String name = uri.getAuthority();
4944        ProviderInfo pi = null;
4945        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
4946                UserHandle.getUserId(callingUid));
4947        if (cpr != null) {
4948            pi = cpr.info;
4949        } else {
4950            try {
4951                pi = pm.resolveContentProvider(name,
4952                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid));
4953            } catch (RemoteException ex) {
4954            }
4955        }
4956        if (pi == null) {
4957            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
4958            return -1;
4959        }
4960
4961        int targetUid = lastTargetUid;
4962        if (targetUid < 0 && targetPkg != null) {
4963            try {
4964                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
4965                if (targetUid < 0) {
4966                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4967                            "Can't grant URI permission no uid for: " + targetPkg);
4968                    return -1;
4969                }
4970            } catch (RemoteException ex) {
4971                return -1;
4972            }
4973        }
4974
4975        if (targetUid >= 0) {
4976            // First...  does the target actually need this permission?
4977            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4978                // No need to grant the target this permission.
4979                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4980                        "Target " + targetPkg + " already has full permission to " + uri);
4981                return -1;
4982            }
4983        } else {
4984            // First...  there is no target package, so can anyone access it?
4985            boolean allowed = pi.exported;
4986            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4987                if (pi.readPermission != null) {
4988                    allowed = false;
4989                }
4990            }
4991            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4992                if (pi.writePermission != null) {
4993                    allowed = false;
4994                }
4995            }
4996            if (allowed) {
4997                return -1;
4998            }
4999        }
5000
5001        // Second...  is the provider allowing granting of URI permissions?
5002        if (!pi.grantUriPermissions) {
5003            throw new SecurityException("Provider " + pi.packageName
5004                    + "/" + pi.name
5005                    + " does not allow granting of Uri permissions (uri "
5006                    + uri + ")");
5007        }
5008        if (pi.uriPermissionPatterns != null) {
5009            final int N = pi.uriPermissionPatterns.length;
5010            boolean allowed = false;
5011            for (int i=0; i<N; i++) {
5012                if (pi.uriPermissionPatterns[i] != null
5013                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5014                    allowed = true;
5015                    break;
5016                }
5017            }
5018            if (!allowed) {
5019                throw new SecurityException("Provider " + pi.packageName
5020                        + "/" + pi.name
5021                        + " does not allow granting of permission to path of Uri "
5022                        + uri);
5023            }
5024        }
5025
5026        // Third...  does the caller itself have permission to access
5027        // this uri?
5028        if (callingUid != Process.myUid()) {
5029            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5030                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5031                    throw new SecurityException("Uid " + callingUid
5032                            + " does not have permission to uri " + uri);
5033                }
5034            }
5035        }
5036
5037        return targetUid;
5038    }
5039
5040    public int checkGrantUriPermission(int callingUid, String targetPkg,
5041            Uri uri, int modeFlags) {
5042        enforceNotIsolatedCaller("checkGrantUriPermission");
5043        synchronized(this) {
5044            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5045        }
5046    }
5047
5048    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5049            Uri uri, int modeFlags, UriPermissionOwner owner) {
5050        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5051                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5052        if (modeFlags == 0) {
5053            return;
5054        }
5055
5056        // So here we are: the caller has the assumed permission
5057        // to the uri, and the target doesn't.  Let's now give this to
5058        // the target.
5059
5060        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5061                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5062
5063        HashMap<Uri, UriPermission> targetUris
5064                = mGrantedUriPermissions.get(targetUid);
5065        if (targetUris == null) {
5066            targetUris = new HashMap<Uri, UriPermission>();
5067            mGrantedUriPermissions.put(targetUid, targetUris);
5068        }
5069
5070        UriPermission perm = targetUris.get(uri);
5071        if (perm == null) {
5072            perm = new UriPermission(targetUid, uri);
5073            targetUris.put(uri, perm);
5074        }
5075
5076        perm.modeFlags |= modeFlags;
5077        if (owner == null) {
5078            perm.globalModeFlags |= modeFlags;
5079        } else {
5080            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5081                 perm.readOwners.add(owner);
5082                 owner.addReadPermission(perm);
5083            }
5084            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5085                 perm.writeOwners.add(owner);
5086                 owner.addWritePermission(perm);
5087            }
5088        }
5089    }
5090
5091    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5092            int modeFlags, UriPermissionOwner owner) {
5093        if (targetPkg == null) {
5094            throw new NullPointerException("targetPkg");
5095        }
5096
5097        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5098        if (targetUid < 0) {
5099            return;
5100        }
5101
5102        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5103    }
5104
5105    static class NeededUriGrants extends ArrayList<Uri> {
5106        final String targetPkg;
5107        final int targetUid;
5108        final int flags;
5109
5110        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5111            targetPkg = _targetPkg;
5112            targetUid = _targetUid;
5113            flags = _flags;
5114        }
5115    }
5116
5117    /**
5118     * Like checkGrantUriPermissionLocked, but takes an Intent.
5119     */
5120    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5121            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5122        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5123                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5124                + " clip=" + (intent != null ? intent.getClipData() : null)
5125                + " from " + intent + "; flags=0x"
5126                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5127
5128        if (targetPkg == null) {
5129            throw new NullPointerException("targetPkg");
5130        }
5131
5132        if (intent == null) {
5133            return null;
5134        }
5135        Uri data = intent.getData();
5136        ClipData clip = intent.getClipData();
5137        if (data == null && clip == null) {
5138            return null;
5139        }
5140        if (data != null) {
5141            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5142                mode, needed != null ? needed.targetUid : -1);
5143            if (target > 0) {
5144                if (needed == null) {
5145                    needed = new NeededUriGrants(targetPkg, target, mode);
5146                }
5147                needed.add(data);
5148            }
5149        }
5150        if (clip != null) {
5151            for (int i=0; i<clip.getItemCount(); i++) {
5152                Uri uri = clip.getItemAt(i).getUri();
5153                if (uri != null) {
5154                    int target = -1;
5155                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5156                            mode, needed != null ? needed.targetUid : -1);
5157                    if (target > 0) {
5158                        if (needed == null) {
5159                            needed = new NeededUriGrants(targetPkg, target, mode);
5160                        }
5161                        needed.add(uri);
5162                    }
5163                } else {
5164                    Intent clipIntent = clip.getItemAt(i).getIntent();
5165                    if (clipIntent != null) {
5166                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5167                                callingUid, targetPkg, clipIntent, mode, needed);
5168                        if (newNeeded != null) {
5169                            needed = newNeeded;
5170                        }
5171                    }
5172                }
5173            }
5174        }
5175
5176        return needed;
5177    }
5178
5179    /**
5180     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5181     */
5182    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5183            UriPermissionOwner owner) {
5184        if (needed != null) {
5185            for (int i=0; i<needed.size(); i++) {
5186                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5187                        needed.get(i), needed.flags, owner);
5188            }
5189        }
5190    }
5191
5192    void grantUriPermissionFromIntentLocked(int callingUid,
5193            String targetPkg, Intent intent, UriPermissionOwner owner) {
5194        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5195                intent, intent != null ? intent.getFlags() : 0, null);
5196        if (needed == null) {
5197            return;
5198        }
5199
5200        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5201    }
5202
5203    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5204            Uri uri, int modeFlags) {
5205        enforceNotIsolatedCaller("grantUriPermission");
5206        synchronized(this) {
5207            final ProcessRecord r = getRecordForAppLocked(caller);
5208            if (r == null) {
5209                throw new SecurityException("Unable to find app for caller "
5210                        + caller
5211                        + " when granting permission to uri " + uri);
5212            }
5213            if (targetPkg == null) {
5214                throw new IllegalArgumentException("null target");
5215            }
5216            if (uri == null) {
5217                throw new IllegalArgumentException("null uri");
5218            }
5219
5220            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5221                    null);
5222        }
5223    }
5224
5225    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5226        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5227                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5228            HashMap<Uri, UriPermission> perms
5229                    = mGrantedUriPermissions.get(perm.uid);
5230            if (perms != null) {
5231                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5232                        "Removing " + perm.uid + " permission to " + perm.uri);
5233                perms.remove(perm.uri);
5234                if (perms.size() == 0) {
5235                    mGrantedUriPermissions.remove(perm.uid);
5236                }
5237            }
5238        }
5239    }
5240
5241    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5242            int modeFlags) {
5243        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5244                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5245        if (modeFlags == 0) {
5246            return;
5247        }
5248
5249        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5250                "Revoking all granted permissions to " + uri);
5251
5252        final IPackageManager pm = AppGlobals.getPackageManager();
5253
5254        final String authority = uri.getAuthority();
5255        ProviderInfo pi = null;
5256        int userId = UserHandle.getUserId(callingUid);
5257        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5258        if (cpr != null) {
5259            pi = cpr.info;
5260        } else {
5261            try {
5262                pi = pm.resolveContentProvider(authority,
5263                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5264            } catch (RemoteException ex) {
5265            }
5266        }
5267        if (pi == null) {
5268            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5269            return;
5270        }
5271
5272        // Does the caller have this permission on the URI?
5273        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5274            // Right now, if you are not the original owner of the permission,
5275            // you are not allowed to revoke it.
5276            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5277                throw new SecurityException("Uid " + callingUid
5278                        + " does not have permission to uri " + uri);
5279            //}
5280        }
5281
5282        // Go through all of the permissions and remove any that match.
5283        final List<String> SEGMENTS = uri.getPathSegments();
5284        if (SEGMENTS != null) {
5285            final int NS = SEGMENTS.size();
5286            int N = mGrantedUriPermissions.size();
5287            for (int i=0; i<N; i++) {
5288                HashMap<Uri, UriPermission> perms
5289                        = mGrantedUriPermissions.valueAt(i);
5290                Iterator<UriPermission> it = perms.values().iterator();
5291            toploop:
5292                while (it.hasNext()) {
5293                    UriPermission perm = it.next();
5294                    Uri targetUri = perm.uri;
5295                    if (!authority.equals(targetUri.getAuthority())) {
5296                        continue;
5297                    }
5298                    List<String> targetSegments = targetUri.getPathSegments();
5299                    if (targetSegments == null) {
5300                        continue;
5301                    }
5302                    if (targetSegments.size() < NS) {
5303                        continue;
5304                    }
5305                    for (int j=0; j<NS; j++) {
5306                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5307                            continue toploop;
5308                        }
5309                    }
5310                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5311                            "Revoking " + perm.uid + " permission to " + perm.uri);
5312                    perm.clearModes(modeFlags);
5313                    if (perm.modeFlags == 0) {
5314                        it.remove();
5315                    }
5316                }
5317                if (perms.size() == 0) {
5318                    mGrantedUriPermissions.remove(
5319                            mGrantedUriPermissions.keyAt(i));
5320                    N--;
5321                    i--;
5322                }
5323            }
5324        }
5325    }
5326
5327    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5328            int modeFlags) {
5329        enforceNotIsolatedCaller("revokeUriPermission");
5330        synchronized(this) {
5331            final ProcessRecord r = getRecordForAppLocked(caller);
5332            if (r == null) {
5333                throw new SecurityException("Unable to find app for caller "
5334                        + caller
5335                        + " when revoking permission to uri " + uri);
5336            }
5337            if (uri == null) {
5338                Slog.w(TAG, "revokeUriPermission: null uri");
5339                return;
5340            }
5341
5342            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5343                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5344            if (modeFlags == 0) {
5345                return;
5346            }
5347
5348            final IPackageManager pm = AppGlobals.getPackageManager();
5349
5350            final String authority = uri.getAuthority();
5351            ProviderInfo pi = null;
5352            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5353            if (cpr != null) {
5354                pi = cpr.info;
5355            } else {
5356                try {
5357                    pi = pm.resolveContentProvider(authority,
5358                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5359                } catch (RemoteException ex) {
5360                }
5361            }
5362            if (pi == null) {
5363                Slog.w(TAG, "No content provider found for permission revoke: "
5364                        + uri.toSafeString());
5365                return;
5366            }
5367
5368            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5369        }
5370    }
5371
5372    @Override
5373    public IBinder newUriPermissionOwner(String name) {
5374        enforceNotIsolatedCaller("newUriPermissionOwner");
5375        synchronized(this) {
5376            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5377            return owner.getExternalTokenLocked();
5378        }
5379    }
5380
5381    @Override
5382    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5383            Uri uri, int modeFlags) {
5384        synchronized(this) {
5385            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5386            if (owner == null) {
5387                throw new IllegalArgumentException("Unknown owner: " + token);
5388            }
5389            if (fromUid != Binder.getCallingUid()) {
5390                if (Binder.getCallingUid() != Process.myUid()) {
5391                    // Only system code can grant URI permissions on behalf
5392                    // of other users.
5393                    throw new SecurityException("nice try");
5394                }
5395            }
5396            if (targetPkg == null) {
5397                throw new IllegalArgumentException("null target");
5398            }
5399            if (uri == null) {
5400                throw new IllegalArgumentException("null uri");
5401            }
5402
5403            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5404        }
5405    }
5406
5407    @Override
5408    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5409        synchronized(this) {
5410            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5411            if (owner == null) {
5412                throw new IllegalArgumentException("Unknown owner: " + token);
5413            }
5414
5415            if (uri == null) {
5416                owner.removeUriPermissionsLocked(mode);
5417            } else {
5418                owner.removeUriPermissionLocked(uri, mode);
5419            }
5420        }
5421    }
5422
5423    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5424        synchronized (this) {
5425            ProcessRecord app =
5426                who != null ? getRecordForAppLocked(who) : null;
5427            if (app == null) return;
5428
5429            Message msg = Message.obtain();
5430            msg.what = WAIT_FOR_DEBUGGER_MSG;
5431            msg.obj = app;
5432            msg.arg1 = waiting ? 1 : 0;
5433            mHandler.sendMessage(msg);
5434        }
5435    }
5436
5437    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5438        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5439        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5440        outInfo.availMem = Process.getFreeMemory();
5441        outInfo.totalMem = Process.getTotalMemory();
5442        outInfo.threshold = homeAppMem;
5443        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5444        outInfo.hiddenAppThreshold = hiddenAppMem;
5445        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5446                ProcessList.SERVICE_ADJ);
5447        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5448                ProcessList.VISIBLE_APP_ADJ);
5449        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5450                ProcessList.FOREGROUND_APP_ADJ);
5451    }
5452
5453    // =========================================================
5454    // TASK MANAGEMENT
5455    // =========================================================
5456
5457    public List getTasks(int maxNum, int flags,
5458                         IThumbnailReceiver receiver) {
5459        ArrayList list = new ArrayList();
5460
5461        PendingThumbnailsRecord pending = null;
5462        IApplicationThread topThumbnail = null;
5463        ActivityRecord topRecord = null;
5464
5465        synchronized(this) {
5466            if (localLOGV) Slog.v(
5467                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5468                + ", receiver=" + receiver);
5469
5470            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5471                    != PackageManager.PERMISSION_GRANTED) {
5472                if (receiver != null) {
5473                    // If the caller wants to wait for pending thumbnails,
5474                    // it ain't gonna get them.
5475                    try {
5476                        receiver.finished();
5477                    } catch (RemoteException ex) {
5478                    }
5479                }
5480                String msg = "Permission Denial: getTasks() from pid="
5481                        + Binder.getCallingPid()
5482                        + ", uid=" + Binder.getCallingUid()
5483                        + " requires " + android.Manifest.permission.GET_TASKS;
5484                Slog.w(TAG, msg);
5485                throw new SecurityException(msg);
5486            }
5487
5488            int pos = mMainStack.mHistory.size()-1;
5489            ActivityRecord next =
5490                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5491            ActivityRecord top = null;
5492            TaskRecord curTask = null;
5493            int numActivities = 0;
5494            int numRunning = 0;
5495            while (pos >= 0 && maxNum > 0) {
5496                final ActivityRecord r = next;
5497                pos--;
5498                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5499
5500                // Initialize state for next task if needed.
5501                if (top == null ||
5502                        (top.state == ActivityState.INITIALIZING
5503                            && top.task == r.task)) {
5504                    top = r;
5505                    curTask = r.task;
5506                    numActivities = numRunning = 0;
5507                }
5508
5509                // Add 'r' into the current task.
5510                numActivities++;
5511                if (r.app != null && r.app.thread != null) {
5512                    numRunning++;
5513                }
5514
5515                if (localLOGV) Slog.v(
5516                    TAG, r.intent.getComponent().flattenToShortString()
5517                    + ": task=" + r.task);
5518
5519                // If the next one is a different task, generate a new
5520                // TaskInfo entry for what we have.
5521                if (next == null || next.task != curTask) {
5522                    ActivityManager.RunningTaskInfo ci
5523                            = new ActivityManager.RunningTaskInfo();
5524                    ci.id = curTask.taskId;
5525                    ci.baseActivity = r.intent.getComponent();
5526                    ci.topActivity = top.intent.getComponent();
5527                    if (top.thumbHolder != null) {
5528                        ci.description = top.thumbHolder.lastDescription;
5529                    }
5530                    ci.numActivities = numActivities;
5531                    ci.numRunning = numRunning;
5532                    //System.out.println(
5533                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5534                    if (ci.thumbnail == null && receiver != null) {
5535                        if (localLOGV) Slog.v(
5536                            TAG, "State=" + top.state + "Idle=" + top.idle
5537                            + " app=" + top.app
5538                            + " thr=" + (top.app != null ? top.app.thread : null));
5539                        if (top.state == ActivityState.RESUMED
5540                                || top.state == ActivityState.PAUSING) {
5541                            if (top.idle && top.app != null
5542                                && top.app.thread != null) {
5543                                topRecord = top;
5544                                topThumbnail = top.app.thread;
5545                            } else {
5546                                top.thumbnailNeeded = true;
5547                            }
5548                        }
5549                        if (pending == null) {
5550                            pending = new PendingThumbnailsRecord(receiver);
5551                        }
5552                        pending.pendingRecords.add(top);
5553                    }
5554                    list.add(ci);
5555                    maxNum--;
5556                    top = null;
5557                }
5558            }
5559
5560            if (pending != null) {
5561                mPendingThumbnails.add(pending);
5562            }
5563        }
5564
5565        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5566
5567        if (topThumbnail != null) {
5568            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5569            try {
5570                topThumbnail.requestThumbnail(topRecord.appToken);
5571            } catch (Exception e) {
5572                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5573                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5574            }
5575        }
5576
5577        if (pending == null && receiver != null) {
5578            // In this case all thumbnails were available and the client
5579            // is being asked to be told when the remaining ones come in...
5580            // which is unusually, since the top-most currently running
5581            // activity should never have a canned thumbnail!  Oh well.
5582            try {
5583                receiver.finished();
5584            } catch (RemoteException ex) {
5585            }
5586        }
5587
5588        return list;
5589    }
5590
5591    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5592            int flags, int userId) {
5593        final int callingUid = Binder.getCallingUid();
5594        if (userId != UserHandle.getCallingUserId()) {
5595            // Check if the caller is holding permissions for cross-user requests.
5596            if (checkComponentPermission(
5597                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5598                    Binder.getCallingPid(), callingUid, -1, true)
5599                    != PackageManager.PERMISSION_GRANTED) {
5600                String msg = "Permission Denial: "
5601                        + "Request to get recent tasks for user " + userId
5602                        + " but is calling from user " + UserHandle.getUserId(callingUid)
5603                        + "; this requires "
5604                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5605                Slog.w(TAG, msg);
5606                throw new SecurityException(msg);
5607            } else {
5608                if (userId == UserHandle.USER_CURRENT) {
5609                    userId = mCurrentUserId;
5610                }
5611            }
5612        }
5613
5614        synchronized (this) {
5615            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5616                    "getRecentTasks()");
5617            final boolean detailed = checkCallingPermission(
5618                    android.Manifest.permission.GET_DETAILED_TASKS)
5619                    == PackageManager.PERMISSION_GRANTED;
5620
5621            IPackageManager pm = AppGlobals.getPackageManager();
5622
5623            final int N = mRecentTasks.size();
5624            ArrayList<ActivityManager.RecentTaskInfo> res
5625                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5626                            maxNum < N ? maxNum : N);
5627            for (int i=0; i<N && maxNum > 0; i++) {
5628                TaskRecord tr = mRecentTasks.get(i);
5629                // Only add calling user's recent tasks
5630                if (tr.userId != userId) continue;
5631                // Return the entry if desired by the caller.  We always return
5632                // the first entry, because callers always expect this to be the
5633                // foreground app.  We may filter others if the caller has
5634                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5635                // we should exclude the entry.
5636
5637                if (i == 0
5638                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5639                        || (tr.intent == null)
5640                        || ((tr.intent.getFlags()
5641                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5642                    ActivityManager.RecentTaskInfo rti
5643                            = new ActivityManager.RecentTaskInfo();
5644                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5645                    rti.persistentId = tr.taskId;
5646                    rti.baseIntent = new Intent(
5647                            tr.intent != null ? tr.intent : tr.affinityIntent);
5648                    if (!detailed) {
5649                        rti.baseIntent.replaceExtras((Bundle)null);
5650                    }
5651                    rti.origActivity = tr.origActivity;
5652                    rti.description = tr.lastDescription;
5653
5654                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5655                        // Check whether this activity is currently available.
5656                        try {
5657                            if (rti.origActivity != null) {
5658                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5659                                        == null) {
5660                                    continue;
5661                                }
5662                            } else if (rti.baseIntent != null) {
5663                                if (pm.queryIntentActivities(rti.baseIntent,
5664                                        null, 0, userId) == null) {
5665                                    continue;
5666                                }
5667                            }
5668                        } catch (RemoteException e) {
5669                            // Will never happen.
5670                        }
5671                    }
5672
5673                    res.add(rti);
5674                    maxNum--;
5675                }
5676            }
5677            return res;
5678        }
5679    }
5680
5681    private TaskRecord taskForIdLocked(int id) {
5682        final int N = mRecentTasks.size();
5683        for (int i=0; i<N; i++) {
5684            TaskRecord tr = mRecentTasks.get(i);
5685            if (tr.taskId == id) {
5686                return tr;
5687            }
5688        }
5689        return null;
5690    }
5691
5692    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5693        synchronized (this) {
5694            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5695                    "getTaskThumbnails()");
5696            TaskRecord tr = taskForIdLocked(id);
5697            if (tr != null) {
5698                return mMainStack.getTaskThumbnailsLocked(tr);
5699            }
5700        }
5701        return null;
5702    }
5703
5704    public boolean removeSubTask(int taskId, int subTaskIndex) {
5705        synchronized (this) {
5706            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5707                    "removeSubTask()");
5708            long ident = Binder.clearCallingIdentity();
5709            try {
5710                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5711                        true) != null;
5712            } finally {
5713                Binder.restoreCallingIdentity(ident);
5714            }
5715        }
5716    }
5717
5718    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5719        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5720        Intent baseIntent = new Intent(
5721                tr.intent != null ? tr.intent : tr.affinityIntent);
5722        ComponentName component = baseIntent.getComponent();
5723        if (component == null) {
5724            Slog.w(TAG, "Now component for base intent of task: " + tr);
5725            return;
5726        }
5727
5728        // Find any running services associated with this app.
5729        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5730
5731        if (killProcesses) {
5732            // Find any running processes associated with this app.
5733            final String pkg = component.getPackageName();
5734            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5735            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5736            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5737                for (int i=0; i<uids.size(); i++) {
5738                    ProcessRecord proc = uids.valueAt(i);
5739                    if (proc.userId != tr.userId) {
5740                        continue;
5741                    }
5742                    if (!proc.pkgList.contains(pkg)) {
5743                        continue;
5744                    }
5745                    procs.add(proc);
5746                }
5747            }
5748
5749            // Kill the running processes.
5750            for (int i=0; i<procs.size(); i++) {
5751                ProcessRecord pr = procs.get(i);
5752                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5753                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5754                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5755                            pr.processName, pr.setAdj, "remove task");
5756                    pr.killedBackground = true;
5757                    Process.killProcessQuiet(pr.pid);
5758                } else {
5759                    pr.waitingToKill = "remove task";
5760                }
5761            }
5762        }
5763    }
5764
5765    public boolean removeTask(int taskId, int flags) {
5766        synchronized (this) {
5767            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5768                    "removeTask()");
5769            long ident = Binder.clearCallingIdentity();
5770            try {
5771                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5772                        false);
5773                if (r != null) {
5774                    mRecentTasks.remove(r.task);
5775                    cleanUpRemovedTaskLocked(r.task, flags);
5776                    return true;
5777                } else {
5778                    TaskRecord tr = null;
5779                    int i=0;
5780                    while (i < mRecentTasks.size()) {
5781                        TaskRecord t = mRecentTasks.get(i);
5782                        if (t.taskId == taskId) {
5783                            tr = t;
5784                            break;
5785                        }
5786                        i++;
5787                    }
5788                    if (tr != null) {
5789                        if (tr.numActivities <= 0) {
5790                            // Caller is just removing a recent task that is
5791                            // not actively running.  That is easy!
5792                            mRecentTasks.remove(i);
5793                            cleanUpRemovedTaskLocked(tr, flags);
5794                            return true;
5795                        } else {
5796                            Slog.w(TAG, "removeTask: task " + taskId
5797                                    + " does not have activities to remove, "
5798                                    + " but numActivities=" + tr.numActivities
5799                                    + ": " + tr);
5800                        }
5801                    }
5802                }
5803            } finally {
5804                Binder.restoreCallingIdentity(ident);
5805            }
5806        }
5807        return false;
5808    }
5809
5810    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5811        int j;
5812        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5813        TaskRecord jt = startTask;
5814
5815        // First look backwards
5816        for (j=startIndex-1; j>=0; j--) {
5817            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5818            if (r.task != jt) {
5819                jt = r.task;
5820                if (affinity.equals(jt.affinity)) {
5821                    return j;
5822                }
5823            }
5824        }
5825
5826        // Now look forwards
5827        final int N = mMainStack.mHistory.size();
5828        jt = startTask;
5829        for (j=startIndex+1; j<N; j++) {
5830            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5831            if (r.task != jt) {
5832                if (affinity.equals(jt.affinity)) {
5833                    return j;
5834                }
5835                jt = r.task;
5836            }
5837        }
5838
5839        // Might it be at the top?
5840        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5841            return N-1;
5842        }
5843
5844        return -1;
5845    }
5846
5847    /**
5848     * TODO: Add mController hook
5849     */
5850    public void moveTaskToFront(int task, int flags, Bundle options) {
5851        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5852                "moveTaskToFront()");
5853
5854        synchronized(this) {
5855            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5856                    Binder.getCallingUid(), "Task to front")) {
5857                ActivityOptions.abort(options);
5858                return;
5859            }
5860            final long origId = Binder.clearCallingIdentity();
5861            try {
5862                TaskRecord tr = taskForIdLocked(task);
5863                if (tr != null) {
5864                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5865                        mMainStack.mUserLeaving = true;
5866                    }
5867                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5868                        // Caller wants the home activity moved with it.  To accomplish this,
5869                        // we'll just move the home task to the top first.
5870                        mMainStack.moveHomeToFrontLocked();
5871                    }
5872                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5873                    return;
5874                }
5875                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5876                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5877                    if (hr.task.taskId == task) {
5878                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5879                            mMainStack.mUserLeaving = true;
5880                        }
5881                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5882                            // Caller wants the home activity moved with it.  To accomplish this,
5883                            // we'll just move the home task to the top first.
5884                            mMainStack.moveHomeToFrontLocked();
5885                        }
5886                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5887                        return;
5888                    }
5889                }
5890            } finally {
5891                Binder.restoreCallingIdentity(origId);
5892            }
5893            ActivityOptions.abort(options);
5894        }
5895    }
5896
5897    public void moveTaskToBack(int task) {
5898        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5899                "moveTaskToBack()");
5900
5901        synchronized(this) {
5902            if (mMainStack.mResumedActivity != null
5903                    && mMainStack.mResumedActivity.task.taskId == task) {
5904                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5905                        Binder.getCallingUid(), "Task to back")) {
5906                    return;
5907                }
5908            }
5909            final long origId = Binder.clearCallingIdentity();
5910            mMainStack.moveTaskToBackLocked(task, null);
5911            Binder.restoreCallingIdentity(origId);
5912        }
5913    }
5914
5915    /**
5916     * Moves an activity, and all of the other activities within the same task, to the bottom
5917     * of the history stack.  The activity's order within the task is unchanged.
5918     *
5919     * @param token A reference to the activity we wish to move
5920     * @param nonRoot If false then this only works if the activity is the root
5921     *                of a task; if true it will work for any activity in a task.
5922     * @return Returns true if the move completed, false if not.
5923     */
5924    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5925        enforceNotIsolatedCaller("moveActivityTaskToBack");
5926        synchronized(this) {
5927            final long origId = Binder.clearCallingIdentity();
5928            int taskId = getTaskForActivityLocked(token, !nonRoot);
5929            if (taskId >= 0) {
5930                return mMainStack.moveTaskToBackLocked(taskId, null);
5931            }
5932            Binder.restoreCallingIdentity(origId);
5933        }
5934        return false;
5935    }
5936
5937    public void moveTaskBackwards(int task) {
5938        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5939                "moveTaskBackwards()");
5940
5941        synchronized(this) {
5942            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5943                    Binder.getCallingUid(), "Task backwards")) {
5944                return;
5945            }
5946            final long origId = Binder.clearCallingIdentity();
5947            moveTaskBackwardsLocked(task);
5948            Binder.restoreCallingIdentity(origId);
5949        }
5950    }
5951
5952    private final void moveTaskBackwardsLocked(int task) {
5953        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5954    }
5955
5956    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5957        synchronized(this) {
5958            return getTaskForActivityLocked(token, onlyRoot);
5959        }
5960    }
5961
5962    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5963        final int N = mMainStack.mHistory.size();
5964        TaskRecord lastTask = null;
5965        for (int i=0; i<N; i++) {
5966            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5967            if (r.appToken == token) {
5968                if (!onlyRoot || lastTask != r.task) {
5969                    return r.task.taskId;
5970                }
5971                return -1;
5972            }
5973            lastTask = r.task;
5974        }
5975
5976        return -1;
5977    }
5978
5979    // =========================================================
5980    // THUMBNAILS
5981    // =========================================================
5982
5983    public void reportThumbnail(IBinder token,
5984            Bitmap thumbnail, CharSequence description) {
5985        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5986        final long origId = Binder.clearCallingIdentity();
5987        sendPendingThumbnail(null, token, thumbnail, description, true);
5988        Binder.restoreCallingIdentity(origId);
5989    }
5990
5991    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5992            Bitmap thumbnail, CharSequence description, boolean always) {
5993        TaskRecord task = null;
5994        ArrayList receivers = null;
5995
5996        //System.out.println("Send pending thumbnail: " + r);
5997
5998        synchronized(this) {
5999            if (r == null) {
6000                r = mMainStack.isInStackLocked(token);
6001                if (r == null) {
6002                    return;
6003                }
6004            }
6005            if (thumbnail == null && r.thumbHolder != null) {
6006                thumbnail = r.thumbHolder.lastThumbnail;
6007                description = r.thumbHolder.lastDescription;
6008            }
6009            if (thumbnail == null && !always) {
6010                // If there is no thumbnail, and this entry is not actually
6011                // going away, then abort for now and pick up the next
6012                // thumbnail we get.
6013                return;
6014            }
6015            task = r.task;
6016
6017            int N = mPendingThumbnails.size();
6018            int i=0;
6019            while (i<N) {
6020                PendingThumbnailsRecord pr =
6021                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6022                //System.out.println("Looking in " + pr.pendingRecords);
6023                if (pr.pendingRecords.remove(r)) {
6024                    if (receivers == null) {
6025                        receivers = new ArrayList();
6026                    }
6027                    receivers.add(pr);
6028                    if (pr.pendingRecords.size() == 0) {
6029                        pr.finished = true;
6030                        mPendingThumbnails.remove(i);
6031                        N--;
6032                        continue;
6033                    }
6034                }
6035                i++;
6036            }
6037        }
6038
6039        if (receivers != null) {
6040            final int N = receivers.size();
6041            for (int i=0; i<N; i++) {
6042                try {
6043                    PendingThumbnailsRecord pr =
6044                        (PendingThumbnailsRecord)receivers.get(i);
6045                    pr.receiver.newThumbnail(
6046                        task != null ? task.taskId : -1, thumbnail, description);
6047                    if (pr.finished) {
6048                        pr.receiver.finished();
6049                    }
6050                } catch (Exception e) {
6051                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6052                }
6053            }
6054        }
6055    }
6056
6057    // =========================================================
6058    // CONTENT PROVIDERS
6059    // =========================================================
6060
6061    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6062        List<ProviderInfo> providers = null;
6063        try {
6064            providers = AppGlobals.getPackageManager().
6065                queryContentProviders(app.processName, app.uid,
6066                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6067        } catch (RemoteException ex) {
6068        }
6069        if (DEBUG_MU)
6070            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6071        int userId = app.userId;
6072        if (providers != null) {
6073            int N = providers.size();
6074            for (int i=0; i<N; i++) {
6075                ProviderInfo cpi =
6076                    (ProviderInfo)providers.get(i);
6077                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6078                        cpi.name, cpi.flags);
6079                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6080                    // This is a singleton provider, but a user besides the
6081                    // default user is asking to initialize a process it runs
6082                    // in...  well, no, it doesn't actually run in this process,
6083                    // it runs in the process of the default user.  Get rid of it.
6084                    providers.remove(i);
6085                    N--;
6086                    continue;
6087                }
6088
6089                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6090                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6091                if (cpr == null) {
6092                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6093                    mProviderMap.putProviderByClass(comp, cpr);
6094                }
6095                if (DEBUG_MU)
6096                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6097                app.pubProviders.put(cpi.name, cpr);
6098                app.addPackage(cpi.applicationInfo.packageName);
6099                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6100            }
6101        }
6102        return providers;
6103    }
6104
6105    /**
6106     * Check if {@link ProcessRecord} has a possible chance at accessing the
6107     * given {@link ProviderInfo}. Final permission checking is always done
6108     * in {@link ContentProvider}.
6109     */
6110    private final String checkContentProviderPermissionLocked(
6111            ProviderInfo cpi, ProcessRecord r) {
6112        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6113        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6114        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6115                cpi.applicationInfo.uid, cpi.exported)
6116                == PackageManager.PERMISSION_GRANTED) {
6117            return null;
6118        }
6119        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6120                cpi.applicationInfo.uid, cpi.exported)
6121                == PackageManager.PERMISSION_GRANTED) {
6122            return null;
6123        }
6124
6125        PathPermission[] pps = cpi.pathPermissions;
6126        if (pps != null) {
6127            int i = pps.length;
6128            while (i > 0) {
6129                i--;
6130                PathPermission pp = pps[i];
6131                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6132                        cpi.applicationInfo.uid, cpi.exported)
6133                        == PackageManager.PERMISSION_GRANTED) {
6134                    return null;
6135                }
6136                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6137                        cpi.applicationInfo.uid, cpi.exported)
6138                        == PackageManager.PERMISSION_GRANTED) {
6139                    return null;
6140                }
6141            }
6142        }
6143
6144        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6145        if (perms != null) {
6146            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6147                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6148                    return null;
6149                }
6150            }
6151        }
6152
6153        String msg;
6154        if (!cpi.exported) {
6155            msg = "Permission Denial: opening provider " + cpi.name
6156                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6157                    + ", uid=" + callingUid + ") that is not exported from uid "
6158                    + cpi.applicationInfo.uid;
6159        } else {
6160            msg = "Permission Denial: opening provider " + cpi.name
6161                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6162                    + ", uid=" + callingUid + ") requires "
6163                    + cpi.readPermission + " or " + cpi.writePermission;
6164        }
6165        Slog.w(TAG, msg);
6166        return msg;
6167    }
6168
6169    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6170            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6171        if (r != null) {
6172            for (int i=0; i<r.conProviders.size(); i++) {
6173                ContentProviderConnection conn = r.conProviders.get(i);
6174                if (conn.provider == cpr) {
6175                    if (DEBUG_PROVIDER) Slog.v(TAG,
6176                            "Adding provider requested by "
6177                            + r.processName + " from process "
6178                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6179                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6180                    if (stable) {
6181                        conn.stableCount++;
6182                        conn.numStableIncs++;
6183                    } else {
6184                        conn.unstableCount++;
6185                        conn.numUnstableIncs++;
6186                    }
6187                    return conn;
6188                }
6189            }
6190            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6191            if (stable) {
6192                conn.stableCount = 1;
6193                conn.numStableIncs = 1;
6194            } else {
6195                conn.unstableCount = 1;
6196                conn.numUnstableIncs = 1;
6197            }
6198            cpr.connections.add(conn);
6199            r.conProviders.add(conn);
6200            return conn;
6201        }
6202        cpr.addExternalProcessHandleLocked(externalProcessToken);
6203        return null;
6204    }
6205
6206    boolean decProviderCountLocked(ContentProviderConnection conn,
6207            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6208        if (conn != null) {
6209            cpr = conn.provider;
6210            if (DEBUG_PROVIDER) Slog.v(TAG,
6211                    "Removing provider requested by "
6212                    + conn.client.processName + " from process "
6213                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6214                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6215            if (stable) {
6216                conn.stableCount--;
6217            } else {
6218                conn.unstableCount--;
6219            }
6220            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6221                cpr.connections.remove(conn);
6222                conn.client.conProviders.remove(conn);
6223                return true;
6224            }
6225            return false;
6226        }
6227        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6228        return false;
6229    }
6230
6231    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6232            String name, IBinder token, boolean stable) {
6233        ContentProviderRecord cpr;
6234        ContentProviderConnection conn = null;
6235        ProviderInfo cpi = null;
6236
6237        synchronized(this) {
6238            ProcessRecord r = null;
6239            if (caller != null) {
6240                r = getRecordForAppLocked(caller);
6241                if (r == null) {
6242                    throw new SecurityException(
6243                            "Unable to find app for caller " + caller
6244                          + " (pid=" + Binder.getCallingPid()
6245                          + ") when getting content provider " + name);
6246                }
6247            }
6248
6249            // First check if this content provider has been published...
6250            int userId = UserHandle.getUserId(r != null ? r.uid : Binder.getCallingUid());
6251            cpr = mProviderMap.getProviderByName(name, userId);
6252            boolean providerRunning = cpr != null;
6253            if (providerRunning) {
6254                cpi = cpr.info;
6255                String msg;
6256                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6257                    throw new SecurityException(msg);
6258                }
6259
6260                if (r != null && cpr.canRunHere(r)) {
6261                    // This provider has been published or is in the process
6262                    // of being published...  but it is also allowed to run
6263                    // in the caller's process, so don't make a connection
6264                    // and just let the caller instantiate its own instance.
6265                    ContentProviderHolder holder = cpr.newHolder(null);
6266                    // don't give caller the provider object, it needs
6267                    // to make its own.
6268                    holder.provider = null;
6269                    return holder;
6270                }
6271
6272                final long origId = Binder.clearCallingIdentity();
6273
6274                // In this case the provider instance already exists, so we can
6275                // return it right away.
6276                conn = incProviderCountLocked(r, cpr, token, stable);
6277                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6278                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6279                        // If this is a perceptible app accessing the provider,
6280                        // make sure to count it as being accessed and thus
6281                        // back up on the LRU list.  This is good because
6282                        // content providers are often expensive to start.
6283                        updateLruProcessLocked(cpr.proc, false, true);
6284                    }
6285                }
6286
6287                if (cpr.proc != null) {
6288                    if (false) {
6289                        if (cpr.name.flattenToShortString().equals(
6290                                "com.android.providers.calendar/.CalendarProvider2")) {
6291                            Slog.v(TAG, "****************** KILLING "
6292                                + cpr.name.flattenToShortString());
6293                            Process.killProcess(cpr.proc.pid);
6294                        }
6295                    }
6296                    boolean success = updateOomAdjLocked(cpr.proc);
6297                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6298                    // NOTE: there is still a race here where a signal could be
6299                    // pending on the process even though we managed to update its
6300                    // adj level.  Not sure what to do about this, but at least
6301                    // the race is now smaller.
6302                    if (!success) {
6303                        // Uh oh...  it looks like the provider's process
6304                        // has been killed on us.  We need to wait for a new
6305                        // process to be started, and make sure its death
6306                        // doesn't kill our process.
6307                        Slog.i(TAG,
6308                                "Existing provider " + cpr.name.flattenToShortString()
6309                                + " is crashing; detaching " + r);
6310                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6311                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6312                        if (!lastRef) {
6313                            // This wasn't the last ref our process had on
6314                            // the provider...  we have now been killed, bail.
6315                            return null;
6316                        }
6317                        providerRunning = false;
6318                        conn = null;
6319                    }
6320                }
6321
6322                Binder.restoreCallingIdentity(origId);
6323            }
6324
6325            boolean singleton;
6326            if (!providerRunning) {
6327                try {
6328                    cpi = AppGlobals.getPackageManager().
6329                        resolveContentProvider(name,
6330                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6331                } catch (RemoteException ex) {
6332                }
6333                if (cpi == null) {
6334                    return null;
6335                }
6336                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6337                        cpi.name, cpi.flags);
6338                if (singleton) {
6339                    userId = 0;
6340                }
6341                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6342
6343                String msg;
6344                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6345                    throw new SecurityException(msg);
6346                }
6347
6348                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6349                        && !cpi.processName.equals("system")) {
6350                    // If this content provider does not run in the system
6351                    // process, and the system is not yet ready to run other
6352                    // processes, then fail fast instead of hanging.
6353                    throw new IllegalArgumentException(
6354                            "Attempt to launch content provider before system ready");
6355                }
6356
6357                // Make sure that the user who owns this provider is started.  If not,
6358                // we don't want to allow it to run.
6359                if (mStartedUsers.get(userId) == null) {
6360                    Slog.w(TAG, "Unable to launch app "
6361                            + cpi.applicationInfo.packageName + "/"
6362                            + cpi.applicationInfo.uid + " for provider "
6363                            + name + ": user " + userId + " is stopped");
6364                    return null;
6365                }
6366
6367                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6368                cpr = mProviderMap.getProviderByClass(comp, userId);
6369                final boolean firstClass = cpr == null;
6370                if (firstClass) {
6371                    try {
6372                        ApplicationInfo ai =
6373                            AppGlobals.getPackageManager().
6374                                getApplicationInfo(
6375                                        cpi.applicationInfo.packageName,
6376                                        STOCK_PM_FLAGS, userId);
6377                        if (ai == null) {
6378                            Slog.w(TAG, "No package info for content provider "
6379                                    + cpi.name);
6380                            return null;
6381                        }
6382                        ai = getAppInfoForUser(ai, userId);
6383                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6384                    } catch (RemoteException ex) {
6385                        // pm is in same process, this will never happen.
6386                    }
6387                }
6388
6389                if (r != null && cpr.canRunHere(r)) {
6390                    // If this is a multiprocess provider, then just return its
6391                    // info and allow the caller to instantiate it.  Only do
6392                    // this if the provider is the same user as the caller's
6393                    // process, or can run as root (so can be in any process).
6394                    return cpr.newHolder(null);
6395                }
6396
6397                if (DEBUG_PROVIDER) {
6398                    RuntimeException e = new RuntimeException("here");
6399                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6400                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6401                }
6402
6403                // This is single process, and our app is now connecting to it.
6404                // See if we are already in the process of launching this
6405                // provider.
6406                final int N = mLaunchingProviders.size();
6407                int i;
6408                for (i=0; i<N; i++) {
6409                    if (mLaunchingProviders.get(i) == cpr) {
6410                        break;
6411                    }
6412                }
6413
6414                // If the provider is not already being launched, then get it
6415                // started.
6416                if (i >= N) {
6417                    final long origId = Binder.clearCallingIdentity();
6418
6419                    try {
6420                        // Content provider is now in use, its package can't be stopped.
6421                        try {
6422                            AppGlobals.getPackageManager().setPackageStoppedState(
6423                                    cpr.appInfo.packageName, false, userId);
6424                        } catch (RemoteException e) {
6425                        } catch (IllegalArgumentException e) {
6426                            Slog.w(TAG, "Failed trying to unstop package "
6427                                    + cpr.appInfo.packageName + ": " + e);
6428                        }
6429
6430                        ProcessRecord proc = startProcessLocked(cpi.processName,
6431                                cpr.appInfo, false, 0, "content provider",
6432                                new ComponentName(cpi.applicationInfo.packageName,
6433                                        cpi.name), false, false);
6434                        if (proc == null) {
6435                            Slog.w(TAG, "Unable to launch app "
6436                                    + cpi.applicationInfo.packageName + "/"
6437                                    + cpi.applicationInfo.uid + " for provider "
6438                                    + name + ": process is bad");
6439                            return null;
6440                        }
6441                        cpr.launchingApp = proc;
6442                        mLaunchingProviders.add(cpr);
6443                    } finally {
6444                        Binder.restoreCallingIdentity(origId);
6445                    }
6446                }
6447
6448                // Make sure the provider is published (the same provider class
6449                // may be published under multiple names).
6450                if (firstClass) {
6451                    mProviderMap.putProviderByClass(comp, cpr);
6452                }
6453
6454                mProviderMap.putProviderByName(name, cpr);
6455                conn = incProviderCountLocked(r, cpr, token, stable);
6456                if (conn != null) {
6457                    conn.waiting = true;
6458                }
6459            }
6460        }
6461
6462        // Wait for the provider to be published...
6463        synchronized (cpr) {
6464            while (cpr.provider == null) {
6465                if (cpr.launchingApp == null) {
6466                    Slog.w(TAG, "Unable to launch app "
6467                            + cpi.applicationInfo.packageName + "/"
6468                            + cpi.applicationInfo.uid + " for provider "
6469                            + name + ": launching app became null");
6470                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6471                            cpi.applicationInfo.packageName,
6472                            cpi.applicationInfo.uid, name);
6473                    return null;
6474                }
6475                try {
6476                    if (DEBUG_MU) {
6477                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6478                                + cpr.launchingApp);
6479                    }
6480                    if (conn != null) {
6481                        conn.waiting = true;
6482                    }
6483                    cpr.wait();
6484                } catch (InterruptedException ex) {
6485                } finally {
6486                    if (conn != null) {
6487                        conn.waiting = false;
6488                    }
6489                }
6490            }
6491        }
6492        return cpr != null ? cpr.newHolder(conn) : null;
6493    }
6494
6495    public final ContentProviderHolder getContentProvider(
6496            IApplicationThread caller, String name, boolean stable) {
6497        enforceNotIsolatedCaller("getContentProvider");
6498        if (caller == null) {
6499            String msg = "null IApplicationThread when getting content provider "
6500                    + name;
6501            Slog.w(TAG, msg);
6502            throw new SecurityException(msg);
6503        }
6504
6505        return getContentProviderImpl(caller, name, null, stable);
6506    }
6507
6508    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6509        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6510            "Do not have permission in call getContentProviderExternal()");
6511        return getContentProviderExternalUnchecked(name, token);
6512    }
6513
6514    private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
6515        return getContentProviderImpl(null, name, token, true);
6516    }
6517
6518    /**
6519     * Drop a content provider from a ProcessRecord's bookkeeping
6520     * @param cpr
6521     */
6522    public void removeContentProvider(IBinder connection, boolean stable) {
6523        enforceNotIsolatedCaller("removeContentProvider");
6524        synchronized (this) {
6525            ContentProviderConnection conn;
6526            try {
6527                conn = (ContentProviderConnection)connection;
6528            } catch (ClassCastException e) {
6529                String msg ="removeContentProvider: " + connection
6530                        + " not a ContentProviderConnection";
6531                Slog.w(TAG, msg);
6532                throw new IllegalArgumentException(msg);
6533            }
6534            if (conn == null) {
6535                throw new NullPointerException("connection is null");
6536            }
6537            if (decProviderCountLocked(conn, null, null, stable)) {
6538                updateOomAdjLocked();
6539            }
6540        }
6541    }
6542
6543    public void removeContentProviderExternal(String name, IBinder token) {
6544        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6545            "Do not have permission in call removeContentProviderExternal()");
6546        removeContentProviderExternalUnchecked(name, token);
6547    }
6548
6549    private void removeContentProviderExternalUnchecked(String name, IBinder token) {
6550        synchronized (this) {
6551            ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6552                    Binder.getOrigCallingUser());
6553            if(cpr == null) {
6554                //remove from mProvidersByClass
6555                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6556                return;
6557            }
6558
6559            //update content provider record entry info
6560            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6561            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
6562                    Binder.getOrigCallingUser());
6563            if (localCpr.hasExternalProcessHandles()) {
6564                if (localCpr.removeExternalProcessHandleLocked(token)) {
6565                    updateOomAdjLocked();
6566                } else {
6567                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6568                            + " with no external reference for token: "
6569                            + token + ".");
6570                }
6571            } else {
6572                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6573                        + " with no external references.");
6574            }
6575        }
6576    }
6577
6578    public final void publishContentProviders(IApplicationThread caller,
6579            List<ContentProviderHolder> providers) {
6580        if (providers == null) {
6581            return;
6582        }
6583
6584        enforceNotIsolatedCaller("publishContentProviders");
6585        synchronized (this) {
6586            final ProcessRecord r = getRecordForAppLocked(caller);
6587            if (DEBUG_MU)
6588                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6589            if (r == null) {
6590                throw new SecurityException(
6591                        "Unable to find app for caller " + caller
6592                      + " (pid=" + Binder.getCallingPid()
6593                      + ") when publishing content providers");
6594            }
6595
6596            final long origId = Binder.clearCallingIdentity();
6597
6598            final int N = providers.size();
6599            for (int i=0; i<N; i++) {
6600                ContentProviderHolder src = providers.get(i);
6601                if (src == null || src.info == null || src.provider == null) {
6602                    continue;
6603                }
6604                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6605                if (DEBUG_MU)
6606                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6607                if (dst != null) {
6608                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6609                    mProviderMap.putProviderByClass(comp, dst);
6610                    String names[] = dst.info.authority.split(";");
6611                    for (int j = 0; j < names.length; j++) {
6612                        mProviderMap.putProviderByName(names[j], dst);
6613                    }
6614
6615                    int NL = mLaunchingProviders.size();
6616                    int j;
6617                    for (j=0; j<NL; j++) {
6618                        if (mLaunchingProviders.get(j) == dst) {
6619                            mLaunchingProviders.remove(j);
6620                            j--;
6621                            NL--;
6622                        }
6623                    }
6624                    synchronized (dst) {
6625                        dst.provider = src.provider;
6626                        dst.proc = r;
6627                        dst.notifyAll();
6628                    }
6629                    updateOomAdjLocked(r);
6630                }
6631            }
6632
6633            Binder.restoreCallingIdentity(origId);
6634        }
6635    }
6636
6637    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6638        ContentProviderConnection conn;
6639        try {
6640            conn = (ContentProviderConnection)connection;
6641        } catch (ClassCastException e) {
6642            String msg ="refContentProvider: " + connection
6643                    + " not a ContentProviderConnection";
6644            Slog.w(TAG, msg);
6645            throw new IllegalArgumentException(msg);
6646        }
6647        if (conn == null) {
6648            throw new NullPointerException("connection is null");
6649        }
6650
6651        synchronized (this) {
6652            if (stable > 0) {
6653                conn.numStableIncs += stable;
6654            }
6655            stable = conn.stableCount + stable;
6656            if (stable < 0) {
6657                throw new IllegalStateException("stableCount < 0: " + stable);
6658            }
6659
6660            if (unstable > 0) {
6661                conn.numUnstableIncs += unstable;
6662            }
6663            unstable = conn.unstableCount + unstable;
6664            if (unstable < 0) {
6665                throw new IllegalStateException("unstableCount < 0: " + unstable);
6666            }
6667
6668            if ((stable+unstable) <= 0) {
6669                throw new IllegalStateException("ref counts can't go to zero here: stable="
6670                        + stable + " unstable=" + unstable);
6671            }
6672            conn.stableCount = stable;
6673            conn.unstableCount = unstable;
6674            return !conn.dead;
6675        }
6676    }
6677
6678    public void unstableProviderDied(IBinder connection) {
6679        ContentProviderConnection conn;
6680        try {
6681            conn = (ContentProviderConnection)connection;
6682        } catch (ClassCastException e) {
6683            String msg ="refContentProvider: " + connection
6684                    + " not a ContentProviderConnection";
6685            Slog.w(TAG, msg);
6686            throw new IllegalArgumentException(msg);
6687        }
6688        if (conn == null) {
6689            throw new NullPointerException("connection is null");
6690        }
6691
6692        // Safely retrieve the content provider associated with the connection.
6693        IContentProvider provider;
6694        synchronized (this) {
6695            provider = conn.provider.provider;
6696        }
6697
6698        if (provider == null) {
6699            // Um, yeah, we're way ahead of you.
6700            return;
6701        }
6702
6703        // Make sure the caller is being honest with us.
6704        if (provider.asBinder().pingBinder()) {
6705            // Er, no, still looks good to us.
6706            synchronized (this) {
6707                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6708                        + " says " + conn + " died, but we don't agree");
6709                return;
6710            }
6711        }
6712
6713        // Well look at that!  It's dead!
6714        synchronized (this) {
6715            if (conn.provider.provider != provider) {
6716                // But something changed...  good enough.
6717                return;
6718            }
6719
6720            ProcessRecord proc = conn.provider.proc;
6721            if (proc == null || proc.thread == null) {
6722                // Seems like the process is already cleaned up.
6723                return;
6724            }
6725
6726            // As far as we're concerned, this is just like receiving a
6727            // death notification...  just a bit prematurely.
6728            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6729                    + ") early provider death");
6730            final long ident = Binder.clearCallingIdentity();
6731            try {
6732                appDiedLocked(proc, proc.pid, proc.thread);
6733            } finally {
6734                Binder.restoreCallingIdentity(ident);
6735            }
6736        }
6737    }
6738
6739    public static final void installSystemProviders() {
6740        List<ProviderInfo> providers;
6741        synchronized (mSelf) {
6742            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6743            providers = mSelf.generateApplicationProvidersLocked(app);
6744            if (providers != null) {
6745                for (int i=providers.size()-1; i>=0; i--) {
6746                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6747                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6748                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6749                                + ": not system .apk");
6750                        providers.remove(i);
6751                    }
6752                }
6753            }
6754        }
6755        if (providers != null) {
6756            mSystemThread.installSystemProviders(providers);
6757        }
6758
6759        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6760
6761        mSelf.mUsageStatsService.monitorPackages();
6762    }
6763
6764    /**
6765     * Allows app to retrieve the MIME type of a URI without having permission
6766     * to access its content provider.
6767     *
6768     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6769     *
6770     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6771     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6772     */
6773    public String getProviderMimeType(Uri uri) {
6774        enforceNotIsolatedCaller("getProviderMimeType");
6775        final String name = uri.getAuthority();
6776        final long ident = Binder.clearCallingIdentity();
6777        ContentProviderHolder holder = null;
6778
6779        try {
6780            holder = getContentProviderExternalUnchecked(name, null);
6781            if (holder != null) {
6782                return holder.provider.getType(uri);
6783            }
6784        } catch (RemoteException e) {
6785            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6786            return null;
6787        } finally {
6788            if (holder != null) {
6789                removeContentProviderExternalUnchecked(name, null);
6790            }
6791            Binder.restoreCallingIdentity(ident);
6792        }
6793
6794        return null;
6795    }
6796
6797    // =========================================================
6798    // GLOBAL MANAGEMENT
6799    // =========================================================
6800
6801    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6802            ApplicationInfo info, String customProcess, boolean isolated) {
6803        String proc = customProcess != null ? customProcess : info.processName;
6804        BatteryStatsImpl.Uid.Proc ps = null;
6805        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6806        int uid = info.uid;
6807        if (isolated) {
6808            int userId = UserHandle.getUserId(uid);
6809            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6810            uid = 0;
6811            while (true) {
6812                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6813                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6814                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6815                }
6816                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6817                mNextIsolatedProcessUid++;
6818                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6819                    // No process for this uid, use it.
6820                    break;
6821                }
6822                stepsLeft--;
6823                if (stepsLeft <= 0) {
6824                    return null;
6825                }
6826            }
6827        }
6828        synchronized (stats) {
6829            ps = stats.getProcessStatsLocked(info.uid, proc);
6830        }
6831        return new ProcessRecord(ps, thread, info, proc, uid);
6832    }
6833
6834    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6835        ProcessRecord app;
6836        if (!isolated) {
6837            app = getProcessRecordLocked(info.processName, info.uid);
6838        } else {
6839            app = null;
6840        }
6841
6842        if (app == null) {
6843            app = newProcessRecordLocked(null, info, null, isolated);
6844            mProcessNames.put(info.processName, app.uid, app);
6845            if (isolated) {
6846                mIsolatedProcesses.put(app.uid, app);
6847            }
6848            updateLruProcessLocked(app, true, true);
6849        }
6850
6851        // This package really, really can not be stopped.
6852        try {
6853            AppGlobals.getPackageManager().setPackageStoppedState(
6854                    info.packageName, false, UserHandle.getUserId(app.uid));
6855        } catch (RemoteException e) {
6856        } catch (IllegalArgumentException e) {
6857            Slog.w(TAG, "Failed trying to unstop package "
6858                    + info.packageName + ": " + e);
6859        }
6860
6861        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6862                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6863            app.persistent = true;
6864            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6865        }
6866        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6867            mPersistentStartingProcesses.add(app);
6868            startProcessLocked(app, "added application", app.processName);
6869        }
6870
6871        return app;
6872    }
6873
6874    public void unhandledBack() {
6875        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6876                "unhandledBack()");
6877
6878        synchronized(this) {
6879            int count = mMainStack.mHistory.size();
6880            if (DEBUG_SWITCH) Slog.d(
6881                TAG, "Performing unhandledBack(): stack size = " + count);
6882            if (count > 1) {
6883                final long origId = Binder.clearCallingIdentity();
6884                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6885                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6886                Binder.restoreCallingIdentity(origId);
6887            }
6888        }
6889    }
6890
6891    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6892        enforceNotIsolatedCaller("openContentUri");
6893        String name = uri.getAuthority();
6894        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
6895        ParcelFileDescriptor pfd = null;
6896        if (cph != null) {
6897            // We record the binder invoker's uid in thread-local storage before
6898            // going to the content provider to open the file.  Later, in the code
6899            // that handles all permissions checks, we look for this uid and use
6900            // that rather than the Activity Manager's own uid.  The effect is that
6901            // we do the check against the caller's permissions even though it looks
6902            // to the content provider like the Activity Manager itself is making
6903            // the request.
6904            sCallerIdentity.set(new Identity(
6905                    Binder.getCallingPid(), Binder.getCallingUid()));
6906            try {
6907                pfd = cph.provider.openFile(uri, "r");
6908            } catch (FileNotFoundException e) {
6909                // do nothing; pfd will be returned null
6910            } finally {
6911                // Ensure that whatever happens, we clean up the identity state
6912                sCallerIdentity.remove();
6913            }
6914
6915            // We've got the fd now, so we're done with the provider.
6916            removeContentProviderExternalUnchecked(name, null);
6917        } else {
6918            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6919        }
6920        return pfd;
6921    }
6922
6923    // Actually is sleeping or shutting down or whatever else in the future
6924    // is an inactive state.
6925    public boolean isSleeping() {
6926        return mSleeping || mShuttingDown;
6927    }
6928
6929    public void goingToSleep() {
6930        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6931                != PackageManager.PERMISSION_GRANTED) {
6932            throw new SecurityException("Requires permission "
6933                    + android.Manifest.permission.DEVICE_POWER);
6934        }
6935
6936        synchronized(this) {
6937            mWentToSleep = true;
6938            updateEventDispatchingLocked();
6939
6940            if (!mSleeping) {
6941                mSleeping = true;
6942                mMainStack.stopIfSleepingLocked();
6943
6944                // Initialize the wake times of all processes.
6945                checkExcessivePowerUsageLocked(false);
6946                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6947                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6948                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6949            }
6950        }
6951    }
6952
6953    public boolean shutdown(int timeout) {
6954        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6955                != PackageManager.PERMISSION_GRANTED) {
6956            throw new SecurityException("Requires permission "
6957                    + android.Manifest.permission.SHUTDOWN);
6958        }
6959
6960        boolean timedout = false;
6961
6962        synchronized(this) {
6963            mShuttingDown = true;
6964            updateEventDispatchingLocked();
6965
6966            if (mMainStack.mResumedActivity != null) {
6967                mMainStack.stopIfSleepingLocked();
6968                final long endTime = System.currentTimeMillis() + timeout;
6969                while (mMainStack.mResumedActivity != null
6970                        || mMainStack.mPausingActivity != null) {
6971                    long delay = endTime - System.currentTimeMillis();
6972                    if (delay <= 0) {
6973                        Slog.w(TAG, "Activity manager shutdown timed out");
6974                        timedout = true;
6975                        break;
6976                    }
6977                    try {
6978                        this.wait();
6979                    } catch (InterruptedException e) {
6980                    }
6981                }
6982            }
6983        }
6984
6985        mUsageStatsService.shutdown();
6986        mBatteryStatsService.shutdown();
6987
6988        return timedout;
6989    }
6990
6991    public final void activitySlept(IBinder token) {
6992        if (localLOGV) Slog.v(
6993            TAG, "Activity slept: token=" + token);
6994
6995        ActivityRecord r = null;
6996
6997        final long origId = Binder.clearCallingIdentity();
6998
6999        synchronized (this) {
7000            r = mMainStack.isInStackLocked(token);
7001            if (r != null) {
7002                mMainStack.activitySleptLocked(r);
7003            }
7004        }
7005
7006        Binder.restoreCallingIdentity(origId);
7007    }
7008
7009    private void comeOutOfSleepIfNeededLocked() {
7010        if (!mWentToSleep && !mLockScreenShown) {
7011            if (mSleeping) {
7012                mSleeping = false;
7013                mMainStack.awakeFromSleepingLocked();
7014                mMainStack.resumeTopActivityLocked(null);
7015            }
7016        }
7017    }
7018
7019    public void wakingUp() {
7020        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7021                != PackageManager.PERMISSION_GRANTED) {
7022            throw new SecurityException("Requires permission "
7023                    + android.Manifest.permission.DEVICE_POWER);
7024        }
7025
7026        synchronized(this) {
7027            mWentToSleep = false;
7028            updateEventDispatchingLocked();
7029            comeOutOfSleepIfNeededLocked();
7030        }
7031    }
7032
7033    private void updateEventDispatchingLocked() {
7034        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7035    }
7036
7037    public void setLockScreenShown(boolean shown) {
7038        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7039                != PackageManager.PERMISSION_GRANTED) {
7040            throw new SecurityException("Requires permission "
7041                    + android.Manifest.permission.DEVICE_POWER);
7042        }
7043
7044        synchronized(this) {
7045            mLockScreenShown = shown;
7046            comeOutOfSleepIfNeededLocked();
7047        }
7048    }
7049
7050    public void stopAppSwitches() {
7051        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7052                != PackageManager.PERMISSION_GRANTED) {
7053            throw new SecurityException("Requires permission "
7054                    + android.Manifest.permission.STOP_APP_SWITCHES);
7055        }
7056
7057        synchronized(this) {
7058            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7059                    + APP_SWITCH_DELAY_TIME;
7060            mDidAppSwitch = false;
7061            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7062            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7063            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7064        }
7065    }
7066
7067    public void resumeAppSwitches() {
7068        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7069                != PackageManager.PERMISSION_GRANTED) {
7070            throw new SecurityException("Requires permission "
7071                    + android.Manifest.permission.STOP_APP_SWITCHES);
7072        }
7073
7074        synchronized(this) {
7075            // Note that we don't execute any pending app switches... we will
7076            // let those wait until either the timeout, or the next start
7077            // activity request.
7078            mAppSwitchesAllowedTime = 0;
7079        }
7080    }
7081
7082    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7083            String name) {
7084        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7085            return true;
7086        }
7087
7088        final int perm = checkComponentPermission(
7089                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7090                callingUid, -1, true);
7091        if (perm == PackageManager.PERMISSION_GRANTED) {
7092            return true;
7093        }
7094
7095        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7096        return false;
7097    }
7098
7099    public void setDebugApp(String packageName, boolean waitForDebugger,
7100            boolean persistent) {
7101        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7102                "setDebugApp()");
7103
7104        // Note that this is not really thread safe if there are multiple
7105        // callers into it at the same time, but that's not a situation we
7106        // care about.
7107        if (persistent) {
7108            final ContentResolver resolver = mContext.getContentResolver();
7109            Settings.System.putString(
7110                resolver, Settings.System.DEBUG_APP,
7111                packageName);
7112            Settings.System.putInt(
7113                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7114                waitForDebugger ? 1 : 0);
7115        }
7116
7117        synchronized (this) {
7118            if (!persistent) {
7119                mOrigDebugApp = mDebugApp;
7120                mOrigWaitForDebugger = mWaitForDebugger;
7121            }
7122            mDebugApp = packageName;
7123            mWaitForDebugger = waitForDebugger;
7124            mDebugTransient = !persistent;
7125            if (packageName != null) {
7126                final long origId = Binder.clearCallingIdentity();
7127                forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
7128                Binder.restoreCallingIdentity(origId);
7129            }
7130        }
7131    }
7132
7133    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7134        synchronized (this) {
7135            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7136            if (!isDebuggable) {
7137                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7138                    throw new SecurityException("Process not debuggable: " + app.packageName);
7139                }
7140            }
7141
7142            mOpenGlTraceApp = processName;
7143        }
7144    }
7145
7146    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7147            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7148        synchronized (this) {
7149            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7150            if (!isDebuggable) {
7151                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7152                    throw new SecurityException("Process not debuggable: " + app.packageName);
7153                }
7154            }
7155            mProfileApp = processName;
7156            mProfileFile = profileFile;
7157            if (mProfileFd != null) {
7158                try {
7159                    mProfileFd.close();
7160                } catch (IOException e) {
7161                }
7162                mProfileFd = null;
7163            }
7164            mProfileFd = profileFd;
7165            mProfileType = 0;
7166            mAutoStopProfiler = autoStopProfiler;
7167        }
7168    }
7169
7170    public void setAlwaysFinish(boolean enabled) {
7171        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7172                "setAlwaysFinish()");
7173
7174        Settings.System.putInt(
7175                mContext.getContentResolver(),
7176                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7177
7178        synchronized (this) {
7179            mAlwaysFinishActivities = enabled;
7180        }
7181    }
7182
7183    public void setActivityController(IActivityController controller) {
7184        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7185                "setActivityController()");
7186        synchronized (this) {
7187            mController = controller;
7188        }
7189    }
7190
7191    public boolean isUserAMonkey() {
7192        // For now the fact that there is a controller implies
7193        // we have a monkey.
7194        synchronized (this) {
7195            return mController != null;
7196        }
7197    }
7198
7199    public void registerProcessObserver(IProcessObserver observer) {
7200        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7201                "registerProcessObserver()");
7202        synchronized (this) {
7203            mProcessObservers.register(observer);
7204        }
7205    }
7206
7207    public void unregisterProcessObserver(IProcessObserver observer) {
7208        synchronized (this) {
7209            mProcessObservers.unregister(observer);
7210        }
7211    }
7212
7213    public void setImmersive(IBinder token, boolean immersive) {
7214        synchronized(this) {
7215            ActivityRecord r = mMainStack.isInStackLocked(token);
7216            if (r == null) {
7217                throw new IllegalArgumentException();
7218            }
7219            r.immersive = immersive;
7220        }
7221    }
7222
7223    public boolean isImmersive(IBinder token) {
7224        synchronized (this) {
7225            ActivityRecord r = mMainStack.isInStackLocked(token);
7226            if (r == null) {
7227                throw new IllegalArgumentException();
7228            }
7229            return r.immersive;
7230        }
7231    }
7232
7233    public boolean isTopActivityImmersive() {
7234        enforceNotIsolatedCaller("startActivity");
7235        synchronized (this) {
7236            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7237            return (r != null) ? r.immersive : false;
7238        }
7239    }
7240
7241    public final void enterSafeMode() {
7242        synchronized(this) {
7243            // It only makes sense to do this before the system is ready
7244            // and started launching other packages.
7245            if (!mSystemReady) {
7246                try {
7247                    AppGlobals.getPackageManager().enterSafeMode();
7248                } catch (RemoteException e) {
7249                }
7250            }
7251        }
7252    }
7253
7254    public final void showSafeModeOverlay() {
7255        View v = LayoutInflater.from(mContext).inflate(
7256                com.android.internal.R.layout.safe_mode, null);
7257        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7258        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7259        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7260        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7261        lp.gravity = Gravity.BOTTOM | Gravity.START;
7262        lp.format = v.getBackground().getOpacity();
7263        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7264                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7265        ((WindowManager)mContext.getSystemService(
7266                Context.WINDOW_SERVICE)).addView(v, lp);
7267    }
7268
7269    public void noteWakeupAlarm(IIntentSender sender) {
7270        if (!(sender instanceof PendingIntentRecord)) {
7271            return;
7272        }
7273        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7274        synchronized (stats) {
7275            if (mBatteryStatsService.isOnBattery()) {
7276                mBatteryStatsService.enforceCallingPermission();
7277                PendingIntentRecord rec = (PendingIntentRecord)sender;
7278                int MY_UID = Binder.getCallingUid();
7279                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7280                BatteryStatsImpl.Uid.Pkg pkg =
7281                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7282                pkg.incWakeupsLocked();
7283            }
7284        }
7285    }
7286
7287    public boolean killPids(int[] pids, String pReason, boolean secure) {
7288        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7289            throw new SecurityException("killPids only available to the system");
7290        }
7291        String reason = (pReason == null) ? "Unknown" : pReason;
7292        // XXX Note: don't acquire main activity lock here, because the window
7293        // manager calls in with its locks held.
7294
7295        boolean killed = false;
7296        synchronized (mPidsSelfLocked) {
7297            int[] types = new int[pids.length];
7298            int worstType = 0;
7299            for (int i=0; i<pids.length; i++) {
7300                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7301                if (proc != null) {
7302                    int type = proc.setAdj;
7303                    types[i] = type;
7304                    if (type > worstType) {
7305                        worstType = type;
7306                    }
7307                }
7308            }
7309
7310            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7311            // then constrain it so we will kill all hidden procs.
7312            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7313                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7314                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7315            }
7316
7317            // If this is not a secure call, don't let it kill processes that
7318            // are important.
7319            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7320                worstType = ProcessList.SERVICE_ADJ;
7321            }
7322
7323            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7324            for (int i=0; i<pids.length; i++) {
7325                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7326                if (proc == null) {
7327                    continue;
7328                }
7329                int adj = proc.setAdj;
7330                if (adj >= worstType && !proc.killedBackground) {
7331                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7332                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7333                            proc.processName, adj, reason);
7334                    killed = true;
7335                    proc.killedBackground = true;
7336                    Process.killProcessQuiet(pids[i]);
7337                }
7338            }
7339        }
7340        return killed;
7341    }
7342
7343    @Override
7344    public boolean killProcessesBelowForeground(String reason) {
7345        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7346            throw new SecurityException("killProcessesBelowForeground() only available to system");
7347        }
7348
7349        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7350    }
7351
7352    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7353        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7354            throw new SecurityException("killProcessesBelowAdj() only available to system");
7355        }
7356
7357        boolean killed = false;
7358        synchronized (mPidsSelfLocked) {
7359            final int size = mPidsSelfLocked.size();
7360            for (int i = 0; i < size; i++) {
7361                final int pid = mPidsSelfLocked.keyAt(i);
7362                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7363                if (proc == null) continue;
7364
7365                final int adj = proc.setAdj;
7366                if (adj > belowAdj && !proc.killedBackground) {
7367                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7368                    EventLog.writeEvent(
7369                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7370                    killed = true;
7371                    proc.killedBackground = true;
7372                    Process.killProcessQuiet(pid);
7373                }
7374            }
7375        }
7376        return killed;
7377    }
7378
7379    public final void startRunning(String pkg, String cls, String action,
7380            String data) {
7381        synchronized(this) {
7382            if (mStartRunning) {
7383                return;
7384            }
7385            mStartRunning = true;
7386            mTopComponent = pkg != null && cls != null
7387                    ? new ComponentName(pkg, cls) : null;
7388            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7389            mTopData = data;
7390            if (!mSystemReady) {
7391                return;
7392            }
7393        }
7394
7395        systemReady(null);
7396    }
7397
7398    private void retrieveSettings() {
7399        final ContentResolver resolver = mContext.getContentResolver();
7400        String debugApp = Settings.System.getString(
7401            resolver, Settings.System.DEBUG_APP);
7402        boolean waitForDebugger = Settings.System.getInt(
7403            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7404        boolean alwaysFinishActivities = Settings.System.getInt(
7405            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7406
7407        Configuration configuration = new Configuration();
7408        Settings.System.getConfiguration(resolver, configuration);
7409
7410        synchronized (this) {
7411            mDebugApp = mOrigDebugApp = debugApp;
7412            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7413            mAlwaysFinishActivities = alwaysFinishActivities;
7414            // This happens before any activities are started, so we can
7415            // change mConfiguration in-place.
7416            updateConfigurationLocked(configuration, null, false, true);
7417            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7418        }
7419    }
7420
7421    public boolean testIsSystemReady() {
7422        // no need to synchronize(this) just to read & return the value
7423        return mSystemReady;
7424    }
7425
7426    private static File getCalledPreBootReceiversFile() {
7427        File dataDir = Environment.getDataDirectory();
7428        File systemDir = new File(dataDir, "system");
7429        File fname = new File(systemDir, "called_pre_boots.dat");
7430        return fname;
7431    }
7432
7433    static final int LAST_DONE_VERSION = 10000;
7434
7435    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7436        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7437        File file = getCalledPreBootReceiversFile();
7438        FileInputStream fis = null;
7439        try {
7440            fis = new FileInputStream(file);
7441            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7442            int fvers = dis.readInt();
7443            if (fvers == LAST_DONE_VERSION) {
7444                String vers = dis.readUTF();
7445                String codename = dis.readUTF();
7446                String build = dis.readUTF();
7447                if (android.os.Build.VERSION.RELEASE.equals(vers)
7448                        && android.os.Build.VERSION.CODENAME.equals(codename)
7449                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7450                    int num = dis.readInt();
7451                    while (num > 0) {
7452                        num--;
7453                        String pkg = dis.readUTF();
7454                        String cls = dis.readUTF();
7455                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7456                    }
7457                }
7458            }
7459        } catch (FileNotFoundException e) {
7460        } catch (IOException e) {
7461            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7462        } finally {
7463            if (fis != null) {
7464                try {
7465                    fis.close();
7466                } catch (IOException e) {
7467                }
7468            }
7469        }
7470        return lastDoneReceivers;
7471    }
7472
7473    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7474        File file = getCalledPreBootReceiversFile();
7475        FileOutputStream fos = null;
7476        DataOutputStream dos = null;
7477        try {
7478            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7479            fos = new FileOutputStream(file);
7480            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7481            dos.writeInt(LAST_DONE_VERSION);
7482            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7483            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7484            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7485            dos.writeInt(list.size());
7486            for (int i=0; i<list.size(); i++) {
7487                dos.writeUTF(list.get(i).getPackageName());
7488                dos.writeUTF(list.get(i).getClassName());
7489            }
7490        } catch (IOException e) {
7491            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7492            file.delete();
7493        } finally {
7494            FileUtils.sync(fos);
7495            if (dos != null) {
7496                try {
7497                    dos.close();
7498                } catch (IOException e) {
7499                    // TODO Auto-generated catch block
7500                    e.printStackTrace();
7501                }
7502            }
7503        }
7504    }
7505
7506    public void systemReady(final Runnable goingCallback) {
7507        synchronized(this) {
7508            if (mSystemReady) {
7509                if (goingCallback != null) goingCallback.run();
7510                return;
7511            }
7512
7513            // Check to see if there are any update receivers to run.
7514            if (!mDidUpdate) {
7515                if (mWaitingUpdate) {
7516                    return;
7517                }
7518                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7519                List<ResolveInfo> ris = null;
7520                try {
7521                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7522                            intent, null, 0, 0);
7523                } catch (RemoteException e) {
7524                }
7525                if (ris != null) {
7526                    for (int i=ris.size()-1; i>=0; i--) {
7527                        if ((ris.get(i).activityInfo.applicationInfo.flags
7528                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7529                            ris.remove(i);
7530                        }
7531                    }
7532                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7533
7534                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7535
7536                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7537                    for (int i=0; i<ris.size(); i++) {
7538                        ActivityInfo ai = ris.get(i).activityInfo;
7539                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7540                        if (lastDoneReceivers.contains(comp)) {
7541                            ris.remove(i);
7542                            i--;
7543                        }
7544                    }
7545
7546                    for (int i=0; i<ris.size(); i++) {
7547                        ActivityInfo ai = ris.get(i).activityInfo;
7548                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7549                        doneReceivers.add(comp);
7550                        intent.setComponent(comp);
7551                        IIntentReceiver finisher = null;
7552                        if (i == ris.size()-1) {
7553                            finisher = new IIntentReceiver.Stub() {
7554                                public void performReceive(Intent intent, int resultCode,
7555                                        String data, Bundle extras, boolean ordered,
7556                                        boolean sticky) {
7557                                    // The raw IIntentReceiver interface is called
7558                                    // with the AM lock held, so redispatch to
7559                                    // execute our code without the lock.
7560                                    mHandler.post(new Runnable() {
7561                                        public void run() {
7562                                            synchronized (ActivityManagerService.this) {
7563                                                mDidUpdate = true;
7564                                            }
7565                                            writeLastDonePreBootReceivers(doneReceivers);
7566                                            showBootMessage(mContext.getText(
7567                                                    R.string.android_upgrading_complete),
7568                                                    false);
7569                                            systemReady(goingCallback);
7570                                        }
7571                                    });
7572                                }
7573                            };
7574                        }
7575                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7576                        /* TODO: Send this to all users */
7577                        broadcastIntentLocked(null, null, intent, null, finisher,
7578                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7579                                0 /* UserId zero */);
7580                        if (finisher != null) {
7581                            mWaitingUpdate = true;
7582                        }
7583                    }
7584                }
7585                if (mWaitingUpdate) {
7586                    return;
7587                }
7588                mDidUpdate = true;
7589            }
7590
7591            mSystemReady = true;
7592            if (!mStartRunning) {
7593                return;
7594            }
7595        }
7596
7597        ArrayList<ProcessRecord> procsToKill = null;
7598        synchronized(mPidsSelfLocked) {
7599            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7600                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7601                if (!isAllowedWhileBooting(proc.info)){
7602                    if (procsToKill == null) {
7603                        procsToKill = new ArrayList<ProcessRecord>();
7604                    }
7605                    procsToKill.add(proc);
7606                }
7607            }
7608        }
7609
7610        synchronized(this) {
7611            if (procsToKill != null) {
7612                for (int i=procsToKill.size()-1; i>=0; i--) {
7613                    ProcessRecord proc = procsToKill.get(i);
7614                    Slog.i(TAG, "Removing system update proc: " + proc);
7615                    removeProcessLocked(proc, true, false, "system update done");
7616                }
7617            }
7618
7619            // Now that we have cleaned up any update processes, we
7620            // are ready to start launching real processes and know that
7621            // we won't trample on them any more.
7622            mProcessesReady = true;
7623        }
7624
7625        Slog.i(TAG, "System now ready");
7626        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7627            SystemClock.uptimeMillis());
7628
7629        synchronized(this) {
7630            // Make sure we have no pre-ready processes sitting around.
7631
7632            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7633                ResolveInfo ri = mContext.getPackageManager()
7634                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7635                                STOCK_PM_FLAGS);
7636                CharSequence errorMsg = null;
7637                if (ri != null) {
7638                    ActivityInfo ai = ri.activityInfo;
7639                    ApplicationInfo app = ai.applicationInfo;
7640                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7641                        mTopAction = Intent.ACTION_FACTORY_TEST;
7642                        mTopData = null;
7643                        mTopComponent = new ComponentName(app.packageName,
7644                                ai.name);
7645                    } else {
7646                        errorMsg = mContext.getResources().getText(
7647                                com.android.internal.R.string.factorytest_not_system);
7648                    }
7649                } else {
7650                    errorMsg = mContext.getResources().getText(
7651                            com.android.internal.R.string.factorytest_no_action);
7652                }
7653                if (errorMsg != null) {
7654                    mTopAction = null;
7655                    mTopData = null;
7656                    mTopComponent = null;
7657                    Message msg = Message.obtain();
7658                    msg.what = SHOW_FACTORY_ERROR_MSG;
7659                    msg.getData().putCharSequence("msg", errorMsg);
7660                    mHandler.sendMessage(msg);
7661                }
7662            }
7663        }
7664
7665        retrieveSettings();
7666
7667        if (goingCallback != null) goingCallback.run();
7668
7669        synchronized (this) {
7670            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7671                try {
7672                    List apps = AppGlobals.getPackageManager().
7673                        getPersistentApplications(STOCK_PM_FLAGS);
7674                    if (apps != null) {
7675                        int N = apps.size();
7676                        int i;
7677                        for (i=0; i<N; i++) {
7678                            ApplicationInfo info
7679                                = (ApplicationInfo)apps.get(i);
7680                            if (info != null &&
7681                                    !info.packageName.equals("android")) {
7682                                addAppLocked(info, false);
7683                            }
7684                        }
7685                    }
7686                } catch (RemoteException ex) {
7687                    // pm is in same process, this will never happen.
7688                }
7689            }
7690
7691            // Start up initial activity.
7692            mBooting = true;
7693
7694            try {
7695                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7696                    Message msg = Message.obtain();
7697                    msg.what = SHOW_UID_ERROR_MSG;
7698                    mHandler.sendMessage(msg);
7699                }
7700            } catch (RemoteException e) {
7701            }
7702
7703            mMainStack.resumeTopActivityLocked(null);
7704        }
7705    }
7706
7707    private boolean makeAppCrashingLocked(ProcessRecord app,
7708            String shortMsg, String longMsg, String stackTrace) {
7709        app.crashing = true;
7710        app.crashingReport = generateProcessError(app,
7711                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7712        startAppProblemLocked(app);
7713        app.stopFreezingAllLocked();
7714        return handleAppCrashLocked(app);
7715    }
7716
7717    private void makeAppNotRespondingLocked(ProcessRecord app,
7718            String activity, String shortMsg, String longMsg) {
7719        app.notResponding = true;
7720        app.notRespondingReport = generateProcessError(app,
7721                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7722                activity, shortMsg, longMsg, null);
7723        startAppProblemLocked(app);
7724        app.stopFreezingAllLocked();
7725    }
7726
7727    /**
7728     * Generate a process error record, suitable for attachment to a ProcessRecord.
7729     *
7730     * @param app The ProcessRecord in which the error occurred.
7731     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7732     *                      ActivityManager.AppErrorStateInfo
7733     * @param activity The activity associated with the crash, if known.
7734     * @param shortMsg Short message describing the crash.
7735     * @param longMsg Long message describing the crash.
7736     * @param stackTrace Full crash stack trace, may be null.
7737     *
7738     * @return Returns a fully-formed AppErrorStateInfo record.
7739     */
7740    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7741            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7742        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7743
7744        report.condition = condition;
7745        report.processName = app.processName;
7746        report.pid = app.pid;
7747        report.uid = app.info.uid;
7748        report.tag = activity;
7749        report.shortMsg = shortMsg;
7750        report.longMsg = longMsg;
7751        report.stackTrace = stackTrace;
7752
7753        return report;
7754    }
7755
7756    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7757        synchronized (this) {
7758            app.crashing = false;
7759            app.crashingReport = null;
7760            app.notResponding = false;
7761            app.notRespondingReport = null;
7762            if (app.anrDialog == fromDialog) {
7763                app.anrDialog = null;
7764            }
7765            if (app.waitDialog == fromDialog) {
7766                app.waitDialog = null;
7767            }
7768            if (app.pid > 0 && app.pid != MY_PID) {
7769                handleAppCrashLocked(app);
7770                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7771                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7772                        app.processName, app.setAdj, "user's request after error");
7773                Process.killProcessQuiet(app.pid);
7774            }
7775        }
7776    }
7777
7778    private boolean handleAppCrashLocked(ProcessRecord app) {
7779        if (mHeadless) {
7780            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7781            return false;
7782        }
7783        long now = SystemClock.uptimeMillis();
7784
7785        Long crashTime;
7786        if (!app.isolated) {
7787            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7788        } else {
7789            crashTime = null;
7790        }
7791        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7792            // This process loses!
7793            Slog.w(TAG, "Process " + app.info.processName
7794                    + " has crashed too many times: killing!");
7795            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7796                    app.info.processName, app.uid);
7797            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7798                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7799                if (r.app == app) {
7800                    Slog.w(TAG, "  Force finishing activity "
7801                        + r.intent.getComponent().flattenToShortString());
7802                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7803                }
7804            }
7805            if (!app.persistent) {
7806                // We don't want to start this process again until the user
7807                // explicitly does so...  but for persistent process, we really
7808                // need to keep it running.  If a persistent process is actually
7809                // repeatedly crashing, then badness for everyone.
7810                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7811                        app.info.processName);
7812                if (!app.isolated) {
7813                    // XXX We don't have a way to mark isolated processes
7814                    // as bad, since they don't have a peristent identity.
7815                    mBadProcesses.put(app.info.processName, app.uid, now);
7816                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7817                }
7818                app.bad = true;
7819                app.removed = true;
7820                // Don't let services in this process be restarted and potentially
7821                // annoy the user repeatedly.  Unless it is persistent, since those
7822                // processes run critical code.
7823                removeProcessLocked(app, false, false, "crash");
7824                mMainStack.resumeTopActivityLocked(null);
7825                return false;
7826            }
7827            mMainStack.resumeTopActivityLocked(null);
7828        } else {
7829            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7830            if (r != null && r.app == app) {
7831                // If the top running activity is from this crashing
7832                // process, then terminate it to avoid getting in a loop.
7833                Slog.w(TAG, "  Force finishing activity "
7834                        + r.intent.getComponent().flattenToShortString());
7835                int index = mMainStack.indexOfActivityLocked(r);
7836                r.stack.finishActivityLocked(r, index,
7837                        Activity.RESULT_CANCELED, null, "crashed");
7838                // Also terminate any activities below it that aren't yet
7839                // stopped, to avoid a situation where one will get
7840                // re-start our crashing activity once it gets resumed again.
7841                index--;
7842                if (index >= 0) {
7843                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7844                    if (r.state == ActivityState.RESUMED
7845                            || r.state == ActivityState.PAUSING
7846                            || r.state == ActivityState.PAUSED) {
7847                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7848                            Slog.w(TAG, "  Force finishing activity "
7849                                    + r.intent.getComponent().flattenToShortString());
7850                            r.stack.finishActivityLocked(r, index,
7851                                    Activity.RESULT_CANCELED, null, "crashed");
7852                        }
7853                    }
7854                }
7855            }
7856        }
7857
7858        // Bump up the crash count of any services currently running in the proc.
7859        if (app.services.size() != 0) {
7860            // Any services running in the application need to be placed
7861            // back in the pending list.
7862            Iterator<ServiceRecord> it = app.services.iterator();
7863            while (it.hasNext()) {
7864                ServiceRecord sr = it.next();
7865                sr.crashCount++;
7866            }
7867        }
7868
7869        // If the crashing process is what we consider to be the "home process" and it has been
7870        // replaced by a third-party app, clear the package preferred activities from packages
7871        // with a home activity running in the process to prevent a repeatedly crashing app
7872        // from blocking the user to manually clear the list.
7873        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7874                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7875            Iterator it = mHomeProcess.activities.iterator();
7876            while (it.hasNext()) {
7877                ActivityRecord r = (ActivityRecord)it.next();
7878                if (r.isHomeActivity) {
7879                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7880                    try {
7881                        ActivityThread.getPackageManager()
7882                                .clearPackagePreferredActivities(r.packageName);
7883                    } catch (RemoteException c) {
7884                        // pm is in same process, this will never happen.
7885                    }
7886                }
7887            }
7888        }
7889
7890        if (!app.isolated) {
7891            // XXX Can't keep track of crash times for isolated processes,
7892            // because they don't have a perisistent identity.
7893            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7894        }
7895
7896        return true;
7897    }
7898
7899    void startAppProblemLocked(ProcessRecord app) {
7900        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7901                mContext, app.info.packageName, app.info.flags);
7902        skipCurrentReceiverLocked(app);
7903    }
7904
7905    void skipCurrentReceiverLocked(ProcessRecord app) {
7906        for (BroadcastQueue queue : mBroadcastQueues) {
7907            queue.skipCurrentReceiverLocked(app);
7908        }
7909    }
7910
7911    /**
7912     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7913     * The application process will exit immediately after this call returns.
7914     * @param app object of the crashing app, null for the system server
7915     * @param crashInfo describing the exception
7916     */
7917    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7918        ProcessRecord r = findAppProcess(app, "Crash");
7919        final String processName = app == null ? "system_server"
7920                : (r == null ? "unknown" : r.processName);
7921
7922        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7923                processName,
7924                r == null ? -1 : r.info.flags,
7925                crashInfo.exceptionClassName,
7926                crashInfo.exceptionMessage,
7927                crashInfo.throwFileName,
7928                crashInfo.throwLineNumber);
7929
7930        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7931
7932        crashApplication(r, crashInfo);
7933    }
7934
7935    public void handleApplicationStrictModeViolation(
7936            IBinder app,
7937            int violationMask,
7938            StrictMode.ViolationInfo info) {
7939        ProcessRecord r = findAppProcess(app, "StrictMode");
7940        if (r == null) {
7941            return;
7942        }
7943
7944        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7945            Integer stackFingerprint = info.hashCode();
7946            boolean logIt = true;
7947            synchronized (mAlreadyLoggedViolatedStacks) {
7948                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7949                    logIt = false;
7950                    // TODO: sub-sample into EventLog for these, with
7951                    // the info.durationMillis?  Then we'd get
7952                    // the relative pain numbers, without logging all
7953                    // the stack traces repeatedly.  We'd want to do
7954                    // likewise in the client code, which also does
7955                    // dup suppression, before the Binder call.
7956                } else {
7957                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7958                        mAlreadyLoggedViolatedStacks.clear();
7959                    }
7960                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7961                }
7962            }
7963            if (logIt) {
7964                logStrictModeViolationToDropBox(r, info);
7965            }
7966        }
7967
7968        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7969            AppErrorResult result = new AppErrorResult();
7970            synchronized (this) {
7971                final long origId = Binder.clearCallingIdentity();
7972
7973                Message msg = Message.obtain();
7974                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7975                HashMap<String, Object> data = new HashMap<String, Object>();
7976                data.put("result", result);
7977                data.put("app", r);
7978                data.put("violationMask", violationMask);
7979                data.put("info", info);
7980                msg.obj = data;
7981                mHandler.sendMessage(msg);
7982
7983                Binder.restoreCallingIdentity(origId);
7984            }
7985            int res = result.get();
7986            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7987        }
7988    }
7989
7990    // Depending on the policy in effect, there could be a bunch of
7991    // these in quick succession so we try to batch these together to
7992    // minimize disk writes, number of dropbox entries, and maximize
7993    // compression, by having more fewer, larger records.
7994    private void logStrictModeViolationToDropBox(
7995            ProcessRecord process,
7996            StrictMode.ViolationInfo info) {
7997        if (info == null) {
7998            return;
7999        }
8000        final boolean isSystemApp = process == null ||
8001                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8002                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8003        final String processName = process == null ? "unknown" : process.processName;
8004        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8005        final DropBoxManager dbox = (DropBoxManager)
8006                mContext.getSystemService(Context.DROPBOX_SERVICE);
8007
8008        // Exit early if the dropbox isn't configured to accept this report type.
8009        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8010
8011        boolean bufferWasEmpty;
8012        boolean needsFlush;
8013        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8014        synchronized (sb) {
8015            bufferWasEmpty = sb.length() == 0;
8016            appendDropBoxProcessHeaders(process, processName, sb);
8017            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8018            sb.append("System-App: ").append(isSystemApp).append("\n");
8019            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8020            if (info.violationNumThisLoop != 0) {
8021                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8022            }
8023            if (info.numAnimationsRunning != 0) {
8024                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8025            }
8026            if (info.broadcastIntentAction != null) {
8027                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8028            }
8029            if (info.durationMillis != -1) {
8030                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8031            }
8032            if (info.numInstances != -1) {
8033                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8034            }
8035            if (info.tags != null) {
8036                for (String tag : info.tags) {
8037                    sb.append("Span-Tag: ").append(tag).append("\n");
8038                }
8039            }
8040            sb.append("\n");
8041            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8042                sb.append(info.crashInfo.stackTrace);
8043            }
8044            sb.append("\n");
8045
8046            // Only buffer up to ~64k.  Various logging bits truncate
8047            // things at 128k.
8048            needsFlush = (sb.length() > 64 * 1024);
8049        }
8050
8051        // Flush immediately if the buffer's grown too large, or this
8052        // is a non-system app.  Non-system apps are isolated with a
8053        // different tag & policy and not batched.
8054        //
8055        // Batching is useful during internal testing with
8056        // StrictMode settings turned up high.  Without batching,
8057        // thousands of separate files could be created on boot.
8058        if (!isSystemApp || needsFlush) {
8059            new Thread("Error dump: " + dropboxTag) {
8060                @Override
8061                public void run() {
8062                    String report;
8063                    synchronized (sb) {
8064                        report = sb.toString();
8065                        sb.delete(0, sb.length());
8066                        sb.trimToSize();
8067                    }
8068                    if (report.length() != 0) {
8069                        dbox.addText(dropboxTag, report);
8070                    }
8071                }
8072            }.start();
8073            return;
8074        }
8075
8076        // System app batching:
8077        if (!bufferWasEmpty) {
8078            // An existing dropbox-writing thread is outstanding, so
8079            // we don't need to start it up.  The existing thread will
8080            // catch the buffer appends we just did.
8081            return;
8082        }
8083
8084        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8085        // (After this point, we shouldn't access AMS internal data structures.)
8086        new Thread("Error dump: " + dropboxTag) {
8087            @Override
8088            public void run() {
8089                // 5 second sleep to let stacks arrive and be batched together
8090                try {
8091                    Thread.sleep(5000);  // 5 seconds
8092                } catch (InterruptedException e) {}
8093
8094                String errorReport;
8095                synchronized (mStrictModeBuffer) {
8096                    errorReport = mStrictModeBuffer.toString();
8097                    if (errorReport.length() == 0) {
8098                        return;
8099                    }
8100                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8101                    mStrictModeBuffer.trimToSize();
8102                }
8103                dbox.addText(dropboxTag, errorReport);
8104            }
8105        }.start();
8106    }
8107
8108    /**
8109     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8110     * @param app object of the crashing app, null for the system server
8111     * @param tag reported by the caller
8112     * @param crashInfo describing the context of the error
8113     * @return true if the process should exit immediately (WTF is fatal)
8114     */
8115    public boolean handleApplicationWtf(IBinder app, String tag,
8116            ApplicationErrorReport.CrashInfo crashInfo) {
8117        ProcessRecord r = findAppProcess(app, "WTF");
8118        final String processName = app == null ? "system_server"
8119                : (r == null ? "unknown" : r.processName);
8120
8121        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8122                processName,
8123                r == null ? -1 : r.info.flags,
8124                tag, crashInfo.exceptionMessage);
8125
8126        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8127
8128        if (r != null && r.pid != Process.myPid() &&
8129                Settings.Secure.getInt(mContext.getContentResolver(),
8130                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8131            crashApplication(r, crashInfo);
8132            return true;
8133        } else {
8134            return false;
8135        }
8136    }
8137
8138    /**
8139     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8140     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8141     */
8142    private ProcessRecord findAppProcess(IBinder app, String reason) {
8143        if (app == null) {
8144            return null;
8145        }
8146
8147        synchronized (this) {
8148            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8149                final int NA = apps.size();
8150                for (int ia=0; ia<NA; ia++) {
8151                    ProcessRecord p = apps.valueAt(ia);
8152                    if (p.thread != null && p.thread.asBinder() == app) {
8153                        return p;
8154                    }
8155                }
8156            }
8157
8158            Slog.w(TAG, "Can't find mystery application for " + reason
8159                    + " from pid=" + Binder.getCallingPid()
8160                    + " uid=" + Binder.getCallingUid() + ": " + app);
8161            return null;
8162        }
8163    }
8164
8165    /**
8166     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8167     * to append various headers to the dropbox log text.
8168     */
8169    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8170            StringBuilder sb) {
8171        // Watchdog thread ends up invoking this function (with
8172        // a null ProcessRecord) to add the stack file to dropbox.
8173        // Do not acquire a lock on this (am) in such cases, as it
8174        // could cause a potential deadlock, if and when watchdog
8175        // is invoked due to unavailability of lock on am and it
8176        // would prevent watchdog from killing system_server.
8177        if (process == null) {
8178            sb.append("Process: ").append(processName).append("\n");
8179            return;
8180        }
8181        // Note: ProcessRecord 'process' is guarded by the service
8182        // instance.  (notably process.pkgList, which could otherwise change
8183        // concurrently during execution of this method)
8184        synchronized (this) {
8185            sb.append("Process: ").append(processName).append("\n");
8186            int flags = process.info.flags;
8187            IPackageManager pm = AppGlobals.getPackageManager();
8188            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8189            for (String pkg : process.pkgList) {
8190                sb.append("Package: ").append(pkg);
8191                try {
8192                    PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
8193                    if (pi != null) {
8194                        sb.append(" v").append(pi.versionCode);
8195                        if (pi.versionName != null) {
8196                            sb.append(" (").append(pi.versionName).append(")");
8197                        }
8198                    }
8199                } catch (RemoteException e) {
8200                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8201                }
8202                sb.append("\n");
8203            }
8204        }
8205    }
8206
8207    private static String processClass(ProcessRecord process) {
8208        if (process == null || process.pid == MY_PID) {
8209            return "system_server";
8210        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8211            return "system_app";
8212        } else {
8213            return "data_app";
8214        }
8215    }
8216
8217    /**
8218     * Write a description of an error (crash, WTF, ANR) to the drop box.
8219     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8220     * @param process which caused the error, null means the system server
8221     * @param activity which triggered the error, null if unknown
8222     * @param parent activity related to the error, null if unknown
8223     * @param subject line related to the error, null if absent
8224     * @param report in long form describing the error, null if absent
8225     * @param logFile to include in the report, null if none
8226     * @param crashInfo giving an application stack trace, null if absent
8227     */
8228    public void addErrorToDropBox(String eventType,
8229            ProcessRecord process, String processName, ActivityRecord activity,
8230            ActivityRecord parent, String subject,
8231            final String report, final File logFile,
8232            final ApplicationErrorReport.CrashInfo crashInfo) {
8233        // NOTE -- this must never acquire the ActivityManagerService lock,
8234        // otherwise the watchdog may be prevented from resetting the system.
8235
8236        final String dropboxTag = processClass(process) + "_" + eventType;
8237        final DropBoxManager dbox = (DropBoxManager)
8238                mContext.getSystemService(Context.DROPBOX_SERVICE);
8239
8240        // Exit early if the dropbox isn't configured to accept this report type.
8241        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8242
8243        final StringBuilder sb = new StringBuilder(1024);
8244        appendDropBoxProcessHeaders(process, processName, sb);
8245        if (activity != null) {
8246            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8247        }
8248        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8249            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8250        }
8251        if (parent != null && parent != activity) {
8252            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8253        }
8254        if (subject != null) {
8255            sb.append("Subject: ").append(subject).append("\n");
8256        }
8257        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8258        if (Debug.isDebuggerConnected()) {
8259            sb.append("Debugger: Connected\n");
8260        }
8261        sb.append("\n");
8262
8263        // Do the rest in a worker thread to avoid blocking the caller on I/O
8264        // (After this point, we shouldn't access AMS internal data structures.)
8265        Thread worker = new Thread("Error dump: " + dropboxTag) {
8266            @Override
8267            public void run() {
8268                if (report != null) {
8269                    sb.append(report);
8270                }
8271                if (logFile != null) {
8272                    try {
8273                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8274                    } catch (IOException e) {
8275                        Slog.e(TAG, "Error reading " + logFile, e);
8276                    }
8277                }
8278                if (crashInfo != null && crashInfo.stackTrace != null) {
8279                    sb.append(crashInfo.stackTrace);
8280                }
8281
8282                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8283                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8284                if (lines > 0) {
8285                    sb.append("\n");
8286
8287                    // Merge several logcat streams, and take the last N lines
8288                    InputStreamReader input = null;
8289                    try {
8290                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8291                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8292                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8293
8294                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8295                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8296                        input = new InputStreamReader(logcat.getInputStream());
8297
8298                        int num;
8299                        char[] buf = new char[8192];
8300                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8301                    } catch (IOException e) {
8302                        Slog.e(TAG, "Error running logcat", e);
8303                    } finally {
8304                        if (input != null) try { input.close(); } catch (IOException e) {}
8305                    }
8306                }
8307
8308                dbox.addText(dropboxTag, sb.toString());
8309            }
8310        };
8311
8312        if (process == null) {
8313            // If process is null, we are being called from some internal code
8314            // and may be about to die -- run this synchronously.
8315            worker.run();
8316        } else {
8317            worker.start();
8318        }
8319    }
8320
8321    /**
8322     * Bring up the "unexpected error" dialog box for a crashing app.
8323     * Deal with edge cases (intercepts from instrumented applications,
8324     * ActivityController, error intent receivers, that sort of thing).
8325     * @param r the application crashing
8326     * @param crashInfo describing the failure
8327     */
8328    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8329        long timeMillis = System.currentTimeMillis();
8330        String shortMsg = crashInfo.exceptionClassName;
8331        String longMsg = crashInfo.exceptionMessage;
8332        String stackTrace = crashInfo.stackTrace;
8333        if (shortMsg != null && longMsg != null) {
8334            longMsg = shortMsg + ": " + longMsg;
8335        } else if (shortMsg != null) {
8336            longMsg = shortMsg;
8337        }
8338
8339        AppErrorResult result = new AppErrorResult();
8340        synchronized (this) {
8341            if (mController != null) {
8342                try {
8343                    String name = r != null ? r.processName : null;
8344                    int pid = r != null ? r.pid : Binder.getCallingPid();
8345                    if (!mController.appCrashed(name, pid,
8346                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8347                        Slog.w(TAG, "Force-killing crashed app " + name
8348                                + " at watcher's request");
8349                        Process.killProcess(pid);
8350                        return;
8351                    }
8352                } catch (RemoteException e) {
8353                    mController = null;
8354                }
8355            }
8356
8357            final long origId = Binder.clearCallingIdentity();
8358
8359            // If this process is running instrumentation, finish it.
8360            if (r != null && r.instrumentationClass != null) {
8361                Slog.w(TAG, "Error in app " + r.processName
8362                      + " running instrumentation " + r.instrumentationClass + ":");
8363                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8364                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8365                Bundle info = new Bundle();
8366                info.putString("shortMsg", shortMsg);
8367                info.putString("longMsg", longMsg);
8368                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8369                Binder.restoreCallingIdentity(origId);
8370                return;
8371            }
8372
8373            // If we can't identify the process or it's already exceeded its crash quota,
8374            // quit right away without showing a crash dialog.
8375            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8376                Binder.restoreCallingIdentity(origId);
8377                return;
8378            }
8379
8380            Message msg = Message.obtain();
8381            msg.what = SHOW_ERROR_MSG;
8382            HashMap data = new HashMap();
8383            data.put("result", result);
8384            data.put("app", r);
8385            msg.obj = data;
8386            mHandler.sendMessage(msg);
8387
8388            Binder.restoreCallingIdentity(origId);
8389        }
8390
8391        int res = result.get();
8392
8393        Intent appErrorIntent = null;
8394        synchronized (this) {
8395            if (r != null && !r.isolated) {
8396                // XXX Can't keep track of crash time for isolated processes,
8397                // since they don't have a persistent identity.
8398                mProcessCrashTimes.put(r.info.processName, r.uid,
8399                        SystemClock.uptimeMillis());
8400            }
8401            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8402                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8403            }
8404        }
8405
8406        if (appErrorIntent != null) {
8407            try {
8408                mContext.startActivity(appErrorIntent);
8409            } catch (ActivityNotFoundException e) {
8410                Slog.w(TAG, "bug report receiver dissappeared", e);
8411            }
8412        }
8413    }
8414
8415    Intent createAppErrorIntentLocked(ProcessRecord r,
8416            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8417        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8418        if (report == null) {
8419            return null;
8420        }
8421        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8422        result.setComponent(r.errorReportReceiver);
8423        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8424        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8425        return result;
8426    }
8427
8428    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8429            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8430        if (r.errorReportReceiver == null) {
8431            return null;
8432        }
8433
8434        if (!r.crashing && !r.notResponding) {
8435            return null;
8436        }
8437
8438        ApplicationErrorReport report = new ApplicationErrorReport();
8439        report.packageName = r.info.packageName;
8440        report.installerPackageName = r.errorReportReceiver.getPackageName();
8441        report.processName = r.processName;
8442        report.time = timeMillis;
8443        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8444
8445        if (r.crashing) {
8446            report.type = ApplicationErrorReport.TYPE_CRASH;
8447            report.crashInfo = crashInfo;
8448        } else if (r.notResponding) {
8449            report.type = ApplicationErrorReport.TYPE_ANR;
8450            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8451
8452            report.anrInfo.activity = r.notRespondingReport.tag;
8453            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8454            report.anrInfo.info = r.notRespondingReport.longMsg;
8455        }
8456
8457        return report;
8458    }
8459
8460    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8461        enforceNotIsolatedCaller("getProcessesInErrorState");
8462        // assume our apps are happy - lazy create the list
8463        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8464
8465        final boolean allUsers = ActivityManager.checkUidPermission(
8466                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8467                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8468        int userId = UserHandle.getUserId(Binder.getCallingUid());
8469
8470        synchronized (this) {
8471
8472            // iterate across all processes
8473            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8474                ProcessRecord app = mLruProcesses.get(i);
8475                if (!allUsers && app.userId != userId) {
8476                    continue;
8477                }
8478                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8479                    // This one's in trouble, so we'll generate a report for it
8480                    // crashes are higher priority (in case there's a crash *and* an anr)
8481                    ActivityManager.ProcessErrorStateInfo report = null;
8482                    if (app.crashing) {
8483                        report = app.crashingReport;
8484                    } else if (app.notResponding) {
8485                        report = app.notRespondingReport;
8486                    }
8487
8488                    if (report != null) {
8489                        if (errList == null) {
8490                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8491                        }
8492                        errList.add(report);
8493                    } else {
8494                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8495                                " crashing = " + app.crashing +
8496                                " notResponding = " + app.notResponding);
8497                    }
8498                }
8499            }
8500        }
8501
8502        return errList;
8503    }
8504
8505    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8506        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8507            if (currApp != null) {
8508                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8509            }
8510            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8511        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8512            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8513        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8514            if (currApp != null) {
8515                currApp.lru = 0;
8516            }
8517            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8518        } else if (adj >= ProcessList.SERVICE_ADJ) {
8519            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8520        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8521            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8522        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8523            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8524        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8525            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8526        } else {
8527            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8528        }
8529    }
8530
8531    private void fillInProcMemInfo(ProcessRecord app,
8532            ActivityManager.RunningAppProcessInfo outInfo) {
8533        outInfo.pid = app.pid;
8534        outInfo.uid = app.info.uid;
8535        if (mHeavyWeightProcess == app) {
8536            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8537        }
8538        if (app.persistent) {
8539            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8540        }
8541        if (app.hasActivities) {
8542            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8543        }
8544        outInfo.lastTrimLevel = app.trimMemoryLevel;
8545        int adj = app.curAdj;
8546        outInfo.importance = oomAdjToImportance(adj, outInfo);
8547        outInfo.importanceReasonCode = app.adjTypeCode;
8548    }
8549
8550    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8551        enforceNotIsolatedCaller("getRunningAppProcesses");
8552        // Lazy instantiation of list
8553        List<ActivityManager.RunningAppProcessInfo> runList = null;
8554        final boolean allUsers = ActivityManager.checkUidPermission(
8555                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8556                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8557        int userId = UserHandle.getUserId(Binder.getCallingUid());
8558        synchronized (this) {
8559            // Iterate across all processes
8560            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8561                ProcessRecord app = mLruProcesses.get(i);
8562                if (!allUsers && app.userId != userId) {
8563                    continue;
8564                }
8565                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8566                    // Generate process state info for running application
8567                    ActivityManager.RunningAppProcessInfo currApp =
8568                        new ActivityManager.RunningAppProcessInfo(app.processName,
8569                                app.pid, app.getPackageList());
8570                    fillInProcMemInfo(app, currApp);
8571                    if (app.adjSource instanceof ProcessRecord) {
8572                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8573                        currApp.importanceReasonImportance = oomAdjToImportance(
8574                                app.adjSourceOom, null);
8575                    } else if (app.adjSource instanceof ActivityRecord) {
8576                        ActivityRecord r = (ActivityRecord)app.adjSource;
8577                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8578                    }
8579                    if (app.adjTarget instanceof ComponentName) {
8580                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8581                    }
8582                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8583                    //        + " lru=" + currApp.lru);
8584                    if (runList == null) {
8585                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8586                    }
8587                    runList.add(currApp);
8588                }
8589            }
8590        }
8591        return runList;
8592    }
8593
8594    public List<ApplicationInfo> getRunningExternalApplications() {
8595        enforceNotIsolatedCaller("getRunningExternalApplications");
8596        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8597        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8598        if (runningApps != null && runningApps.size() > 0) {
8599            Set<String> extList = new HashSet<String>();
8600            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8601                if (app.pkgList != null) {
8602                    for (String pkg : app.pkgList) {
8603                        extList.add(pkg);
8604                    }
8605                }
8606            }
8607            IPackageManager pm = AppGlobals.getPackageManager();
8608            for (String pkg : extList) {
8609                try {
8610                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8611                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8612                        retList.add(info);
8613                    }
8614                } catch (RemoteException e) {
8615                }
8616            }
8617        }
8618        return retList;
8619    }
8620
8621    @Override
8622    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8623        enforceNotIsolatedCaller("getMyMemoryState");
8624        synchronized (this) {
8625            ProcessRecord proc;
8626            synchronized (mPidsSelfLocked) {
8627                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8628            }
8629            fillInProcMemInfo(proc, outInfo);
8630        }
8631    }
8632
8633    @Override
8634    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8635        if (checkCallingPermission(android.Manifest.permission.DUMP)
8636                != PackageManager.PERMISSION_GRANTED) {
8637            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8638                    + Binder.getCallingPid()
8639                    + ", uid=" + Binder.getCallingUid()
8640                    + " without permission "
8641                    + android.Manifest.permission.DUMP);
8642            return;
8643        }
8644
8645        boolean dumpAll = false;
8646        boolean dumpClient = false;
8647        String dumpPackage = null;
8648
8649        int opti = 0;
8650        while (opti < args.length) {
8651            String opt = args[opti];
8652            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8653                break;
8654            }
8655            opti++;
8656            if ("-a".equals(opt)) {
8657                dumpAll = true;
8658            } else if ("-c".equals(opt)) {
8659                dumpClient = true;
8660            } else if ("-h".equals(opt)) {
8661                pw.println("Activity manager dump options:");
8662                pw.println("  [-a] [-c] [-h] [cmd] ...");
8663                pw.println("  cmd may be one of:");
8664                pw.println("    a[ctivities]: activity stack state");
8665                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8666                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8667                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8668                pw.println("    o[om]: out of memory management");
8669                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8670                pw.println("    provider [COMP_SPEC]: provider client-side state");
8671                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8672                pw.println("    service [COMP_SPEC]: service client-side state");
8673                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8674                pw.println("    all: dump all activities");
8675                pw.println("    top: dump the top activity");
8676                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8677                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8678                pw.println("    a partial substring in a component name, a");
8679                pw.println("    hex object identifier.");
8680                pw.println("  -a: include all available server state.");
8681                pw.println("  -c: include client state.");
8682                return;
8683            } else {
8684                pw.println("Unknown argument: " + opt + "; use -h for help");
8685            }
8686        }
8687
8688        long origId = Binder.clearCallingIdentity();
8689        boolean more = false;
8690        // Is the caller requesting to dump a particular piece of data?
8691        if (opti < args.length) {
8692            String cmd = args[opti];
8693            opti++;
8694            if ("activities".equals(cmd) || "a".equals(cmd)) {
8695                synchronized (this) {
8696                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8697                }
8698            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8699                String[] newArgs;
8700                String name;
8701                if (opti >= args.length) {
8702                    name = null;
8703                    newArgs = EMPTY_STRING_ARRAY;
8704                } else {
8705                    name = args[opti];
8706                    opti++;
8707                    newArgs = new String[args.length - opti];
8708                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8709                            args.length - opti);
8710                }
8711                synchronized (this) {
8712                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8713                }
8714            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8715                String[] newArgs;
8716                String name;
8717                if (opti >= args.length) {
8718                    name = null;
8719                    newArgs = EMPTY_STRING_ARRAY;
8720                } else {
8721                    name = args[opti];
8722                    opti++;
8723                    newArgs = new String[args.length - opti];
8724                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8725                            args.length - opti);
8726                }
8727                synchronized (this) {
8728                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8729                }
8730            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8731                String[] newArgs;
8732                String name;
8733                if (opti >= args.length) {
8734                    name = null;
8735                    newArgs = EMPTY_STRING_ARRAY;
8736                } else {
8737                    name = args[opti];
8738                    opti++;
8739                    newArgs = new String[args.length - opti];
8740                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8741                            args.length - opti);
8742                }
8743                synchronized (this) {
8744                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8745                }
8746            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8747                synchronized (this) {
8748                    dumpOomLocked(fd, pw, args, opti, true);
8749                }
8750            } else if ("provider".equals(cmd)) {
8751                String[] newArgs;
8752                String name;
8753                if (opti >= args.length) {
8754                    name = null;
8755                    newArgs = EMPTY_STRING_ARRAY;
8756                } else {
8757                    name = args[opti];
8758                    opti++;
8759                    newArgs = new String[args.length - opti];
8760                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8761                }
8762                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8763                    pw.println("No providers match: " + name);
8764                    pw.println("Use -h for help.");
8765                }
8766            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8767                synchronized (this) {
8768                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8769                }
8770            } else if ("service".equals(cmd)) {
8771                String[] newArgs;
8772                String name;
8773                if (opti >= args.length) {
8774                    name = null;
8775                    newArgs = EMPTY_STRING_ARRAY;
8776                } else {
8777                    name = args[opti];
8778                    opti++;
8779                    newArgs = new String[args.length - opti];
8780                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8781                            args.length - opti);
8782                }
8783                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8784                    pw.println("No services match: " + name);
8785                    pw.println("Use -h for help.");
8786                }
8787            } else if ("package".equals(cmd)) {
8788                String[] newArgs;
8789                if (opti >= args.length) {
8790                    pw.println("package: no package name specified");
8791                    pw.println("Use -h for help.");
8792                } else {
8793                    dumpPackage = args[opti];
8794                    opti++;
8795                    newArgs = new String[args.length - opti];
8796                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8797                            args.length - opti);
8798                    args = newArgs;
8799                    opti = 0;
8800                    more = true;
8801                }
8802            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8803                synchronized (this) {
8804                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8805                }
8806            } else {
8807                // Dumping a single activity?
8808                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8809                    pw.println("Bad activity command, or no activities match: " + cmd);
8810                    pw.println("Use -h for help.");
8811                }
8812            }
8813            if (!more) {
8814                Binder.restoreCallingIdentity(origId);
8815                return;
8816            }
8817        }
8818
8819        // No piece of data specified, dump everything.
8820        synchronized (this) {
8821            boolean needSep;
8822            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8823            if (needSep) {
8824                pw.println(" ");
8825            }
8826            if (dumpAll) {
8827                pw.println("-------------------------------------------------------------------------------");
8828            }
8829            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8830            if (needSep) {
8831                pw.println(" ");
8832            }
8833            if (dumpAll) {
8834                pw.println("-------------------------------------------------------------------------------");
8835            }
8836            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8837            if (needSep) {
8838                pw.println(" ");
8839            }
8840            if (dumpAll) {
8841                pw.println("-------------------------------------------------------------------------------");
8842            }
8843            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8844            if (needSep) {
8845                pw.println(" ");
8846            }
8847            if (dumpAll) {
8848                pw.println("-------------------------------------------------------------------------------");
8849            }
8850            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8851            if (needSep) {
8852                pw.println(" ");
8853            }
8854            if (dumpAll) {
8855                pw.println("-------------------------------------------------------------------------------");
8856            }
8857            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8858        }
8859        Binder.restoreCallingIdentity(origId);
8860    }
8861
8862    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8863            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8864        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8865        pw.println("  Main stack:");
8866        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8867                dumpPackage);
8868        pw.println(" ");
8869        pw.println("  Running activities (most recent first):");
8870        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8871                dumpPackage);
8872        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8873            pw.println(" ");
8874            pw.println("  Activities waiting for another to become visible:");
8875            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8876                    !dumpAll, false, dumpPackage);
8877        }
8878        if (mMainStack.mStoppingActivities.size() > 0) {
8879            pw.println(" ");
8880            pw.println("  Activities waiting to stop:");
8881            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8882                    !dumpAll, false, dumpPackage);
8883        }
8884        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8885            pw.println(" ");
8886            pw.println("  Activities waiting to sleep:");
8887            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8888                    !dumpAll, false, dumpPackage);
8889        }
8890        if (mMainStack.mFinishingActivities.size() > 0) {
8891            pw.println(" ");
8892            pw.println("  Activities waiting to finish:");
8893            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8894                    !dumpAll, false, dumpPackage);
8895        }
8896
8897        pw.println(" ");
8898        if (mMainStack.mPausingActivity != null) {
8899            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8900        }
8901        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8902        pw.println("  mFocusedActivity: " + mFocusedActivity);
8903        if (dumpAll) {
8904            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8905            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8906            pw.println("  mDismissKeyguardOnNextActivity: "
8907                    + mMainStack.mDismissKeyguardOnNextActivity);
8908        }
8909
8910        if (mRecentTasks.size() > 0) {
8911            pw.println();
8912            pw.println("  Recent tasks:");
8913
8914            final int N = mRecentTasks.size();
8915            for (int i=0; i<N; i++) {
8916                TaskRecord tr = mRecentTasks.get(i);
8917                if (dumpPackage != null) {
8918                    if (tr.realActivity == null ||
8919                            !dumpPackage.equals(tr.realActivity)) {
8920                        continue;
8921                    }
8922                }
8923                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8924                        pw.println(tr);
8925                if (dumpAll) {
8926                    mRecentTasks.get(i).dump(pw, "    ");
8927                }
8928            }
8929        }
8930
8931        if (dumpAll) {
8932            pw.println(" ");
8933            pw.println("  mCurTask: " + mCurTask);
8934        }
8935
8936        return true;
8937    }
8938
8939    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8940            int opti, boolean dumpAll, String dumpPackage) {
8941        boolean needSep = false;
8942        int numPers = 0;
8943
8944        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8945
8946        if (dumpAll) {
8947            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8948                final int NA = procs.size();
8949                for (int ia=0; ia<NA; ia++) {
8950                    ProcessRecord r = procs.valueAt(ia);
8951                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8952                        continue;
8953                    }
8954                    if (!needSep) {
8955                        pw.println("  All known processes:");
8956                        needSep = true;
8957                    }
8958                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8959                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8960                        pw.print(" "); pw.println(r);
8961                    r.dump(pw, "    ");
8962                    if (r.persistent) {
8963                        numPers++;
8964                    }
8965                }
8966            }
8967        }
8968
8969        if (mIsolatedProcesses.size() > 0) {
8970            if (needSep) pw.println(" ");
8971            needSep = true;
8972            pw.println("  Isolated process list (sorted by uid):");
8973            for (int i=0; i<mIsolatedProcesses.size(); i++) {
8974                ProcessRecord r = mIsolatedProcesses.valueAt(i);
8975                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8976                    continue;
8977                }
8978                pw.println(String.format("%sIsolated #%2d: %s",
8979                        "    ", i, r.toString()));
8980            }
8981        }
8982
8983        if (mLruProcesses.size() > 0) {
8984            if (needSep) pw.println(" ");
8985            needSep = true;
8986            pw.println("  Process LRU list (sorted by oom_adj):");
8987            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8988                    "Proc", "PERS", false, dumpPackage);
8989            needSep = true;
8990        }
8991
8992        if (dumpAll) {
8993            synchronized (mPidsSelfLocked) {
8994                boolean printed = false;
8995                for (int i=0; i<mPidsSelfLocked.size(); i++) {
8996                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
8997                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8998                        continue;
8999                    }
9000                    if (!printed) {
9001                        if (needSep) pw.println(" ");
9002                        needSep = true;
9003                        pw.println("  PID mappings:");
9004                        printed = true;
9005                    }
9006                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9007                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9008                }
9009            }
9010        }
9011
9012        if (mForegroundProcesses.size() > 0) {
9013            synchronized (mPidsSelfLocked) {
9014                boolean printed = false;
9015                for (int i=0; i<mForegroundProcesses.size(); i++) {
9016                    ProcessRecord r = mPidsSelfLocked.get(
9017                            mForegroundProcesses.valueAt(i).pid);
9018                    if (dumpPackage != null && (r == null
9019                            || !dumpPackage.equals(r.info.packageName))) {
9020                        continue;
9021                    }
9022                    if (!printed) {
9023                        if (needSep) pw.println(" ");
9024                        needSep = true;
9025                        pw.println("  Foreground Processes:");
9026                        printed = true;
9027                    }
9028                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9029                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9030                }
9031            }
9032        }
9033
9034        if (mPersistentStartingProcesses.size() > 0) {
9035            if (needSep) pw.println(" ");
9036            needSep = true;
9037            pw.println("  Persisent processes that are starting:");
9038            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9039                    "Starting Norm", "Restarting PERS", dumpPackage);
9040        }
9041
9042        if (mRemovedProcesses.size() > 0) {
9043            if (needSep) pw.println(" ");
9044            needSep = true;
9045            pw.println("  Processes that are being removed:");
9046            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9047                    "Removed Norm", "Removed PERS", dumpPackage);
9048        }
9049
9050        if (mProcessesOnHold.size() > 0) {
9051            if (needSep) pw.println(" ");
9052            needSep = true;
9053            pw.println("  Processes that are on old until the system is ready:");
9054            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9055                    "OnHold Norm", "OnHold PERS", dumpPackage);
9056        }
9057
9058        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9059
9060        if (mProcessCrashTimes.getMap().size() > 0) {
9061            boolean printed = false;
9062            long now = SystemClock.uptimeMillis();
9063            for (Map.Entry<String, SparseArray<Long>> procs
9064                    : mProcessCrashTimes.getMap().entrySet()) {
9065                String pname = procs.getKey();
9066                SparseArray<Long> uids = procs.getValue();
9067                final int N = uids.size();
9068                for (int i=0; i<N; i++) {
9069                    int puid = uids.keyAt(i);
9070                    ProcessRecord r = mProcessNames.get(pname, puid);
9071                    if (dumpPackage != null && (r == null
9072                            || !dumpPackage.equals(r.info.packageName))) {
9073                        continue;
9074                    }
9075                    if (!printed) {
9076                        if (needSep) pw.println(" ");
9077                        needSep = true;
9078                        pw.println("  Time since processes crashed:");
9079                        printed = true;
9080                    }
9081                    pw.print("    Process "); pw.print(pname);
9082                            pw.print(" uid "); pw.print(puid);
9083                            pw.print(": last crashed ");
9084                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9085                            pw.println(" ago");
9086                }
9087            }
9088        }
9089
9090        if (mBadProcesses.getMap().size() > 0) {
9091            boolean printed = false;
9092            for (Map.Entry<String, SparseArray<Long>> procs
9093                    : mBadProcesses.getMap().entrySet()) {
9094                String pname = procs.getKey();
9095                SparseArray<Long> uids = procs.getValue();
9096                final int N = uids.size();
9097                for (int i=0; i<N; i++) {
9098                    int puid = uids.keyAt(i);
9099                    ProcessRecord r = mProcessNames.get(pname, puid);
9100                    if (dumpPackage != null && (r == null
9101                            || !dumpPackage.equals(r.info.packageName))) {
9102                        continue;
9103                    }
9104                    if (!printed) {
9105                        if (needSep) pw.println(" ");
9106                        needSep = true;
9107                        pw.println("  Bad processes:");
9108                    }
9109                    pw.print("    Bad process "); pw.print(pname);
9110                            pw.print(" uid "); pw.print(puid);
9111                            pw.print(": crashed at time ");
9112                            pw.println(uids.valueAt(i));
9113                }
9114            }
9115        }
9116
9117        pw.println();
9118        pw.println("  mStartedUsers:");
9119        for (int i=0; i<mStartedUsers.size(); i++) {
9120            UserStartedState uss = mStartedUsers.valueAt(i);
9121            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9122                    pw.println(":");
9123            uss.dump("      ", pw);
9124        }
9125        pw.println("  mHomeProcess: " + mHomeProcess);
9126        pw.println("  mPreviousProcess: " + mPreviousProcess);
9127        if (dumpAll) {
9128            StringBuilder sb = new StringBuilder(128);
9129            sb.append("  mPreviousProcessVisibleTime: ");
9130            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9131            pw.println(sb);
9132        }
9133        if (mHeavyWeightProcess != null) {
9134            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9135        }
9136        pw.println("  mConfiguration: " + mConfiguration);
9137        if (dumpAll) {
9138            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9139            if (mCompatModePackages.getPackages().size() > 0) {
9140                boolean printed = false;
9141                for (Map.Entry<String, Integer> entry
9142                        : mCompatModePackages.getPackages().entrySet()) {
9143                    String pkg = entry.getKey();
9144                    int mode = entry.getValue();
9145                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9146                        continue;
9147                    }
9148                    if (!printed) {
9149                        pw.println("  mScreenCompatPackages:");
9150                        printed = true;
9151                    }
9152                    pw.print("    "); pw.print(pkg); pw.print(": ");
9153                            pw.print(mode); pw.println();
9154                }
9155            }
9156        }
9157        if (mSleeping || mWentToSleep || mLockScreenShown) {
9158            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9159                    + " mLockScreenShown " + mLockScreenShown);
9160        }
9161        if (mShuttingDown) {
9162            pw.println("  mShuttingDown=" + mShuttingDown);
9163        }
9164        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9165                || mOrigWaitForDebugger) {
9166            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9167                    + " mDebugTransient=" + mDebugTransient
9168                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9169        }
9170        if (mOpenGlTraceApp != null) {
9171            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9172        }
9173        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9174                || mProfileFd != null) {
9175            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9176            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9177            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9178                    + mAutoStopProfiler);
9179        }
9180        if (mAlwaysFinishActivities || mController != null) {
9181            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9182                    + " mController=" + mController);
9183        }
9184        if (dumpAll) {
9185            pw.println("  Total persistent processes: " + numPers);
9186            pw.println("  mStartRunning=" + mStartRunning
9187                    + " mProcessesReady=" + mProcessesReady
9188                    + " mSystemReady=" + mSystemReady);
9189            pw.println("  mBooting=" + mBooting
9190                    + " mBooted=" + mBooted
9191                    + " mFactoryTest=" + mFactoryTest);
9192            pw.print("  mLastPowerCheckRealtime=");
9193                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9194                    pw.println("");
9195            pw.print("  mLastPowerCheckUptime=");
9196                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9197                    pw.println("");
9198            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9199            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9200            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9201            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9202                    + " mNumHiddenProcs=" + mNumHiddenProcs
9203                    + " mNumServiceProcs=" + mNumServiceProcs
9204                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9205        }
9206
9207        return true;
9208    }
9209
9210    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9211            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9212        if (mProcessesToGc.size() > 0) {
9213            boolean printed = false;
9214            long now = SystemClock.uptimeMillis();
9215            for (int i=0; i<mProcessesToGc.size(); i++) {
9216                ProcessRecord proc = mProcessesToGc.get(i);
9217                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9218                    continue;
9219                }
9220                if (!printed) {
9221                    if (needSep) pw.println(" ");
9222                    needSep = true;
9223                    pw.println("  Processes that are waiting to GC:");
9224                    printed = true;
9225                }
9226                pw.print("    Process "); pw.println(proc);
9227                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9228                        pw.print(", last gced=");
9229                        pw.print(now-proc.lastRequestedGc);
9230                        pw.print(" ms ago, last lowMem=");
9231                        pw.print(now-proc.lastLowMemory);
9232                        pw.println(" ms ago");
9233
9234            }
9235        }
9236        return needSep;
9237    }
9238
9239    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9240            int opti, boolean dumpAll) {
9241        boolean needSep = false;
9242
9243        if (mLruProcesses.size() > 0) {
9244            if (needSep) pw.println(" ");
9245            needSep = true;
9246            pw.println("  OOM levels:");
9247            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9248            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9249            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9250            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9251            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9252            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9253            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9254            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9255            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9256            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9257            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9258            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9259            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9260
9261            if (needSep) pw.println(" ");
9262            needSep = true;
9263            pw.println("  Process OOM control:");
9264            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9265                    "Proc", "PERS", true, null);
9266            needSep = true;
9267        }
9268
9269        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9270
9271        pw.println();
9272        pw.println("  mHomeProcess: " + mHomeProcess);
9273        pw.println("  mPreviousProcess: " + mPreviousProcess);
9274        if (mHeavyWeightProcess != null) {
9275            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9276        }
9277
9278        return true;
9279    }
9280
9281    /**
9282     * There are three ways to call this:
9283     *  - no provider specified: dump all the providers
9284     *  - a flattened component name that matched an existing provider was specified as the
9285     *    first arg: dump that one provider
9286     *  - the first arg isn't the flattened component name of an existing provider:
9287     *    dump all providers whose component contains the first arg as a substring
9288     */
9289    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9290            int opti, boolean dumpAll) {
9291        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9292    }
9293
9294    static class ItemMatcher {
9295        ArrayList<ComponentName> components;
9296        ArrayList<String> strings;
9297        ArrayList<Integer> objects;
9298        boolean all;
9299
9300        ItemMatcher() {
9301            all = true;
9302        }
9303
9304        void build(String name) {
9305            ComponentName componentName = ComponentName.unflattenFromString(name);
9306            if (componentName != null) {
9307                if (components == null) {
9308                    components = new ArrayList<ComponentName>();
9309                }
9310                components.add(componentName);
9311                all = false;
9312            } else {
9313                int objectId = 0;
9314                // Not a '/' separated full component name; maybe an object ID?
9315                try {
9316                    objectId = Integer.parseInt(name, 16);
9317                    if (objects == null) {
9318                        objects = new ArrayList<Integer>();
9319                    }
9320                    objects.add(objectId);
9321                    all = false;
9322                } catch (RuntimeException e) {
9323                    // Not an integer; just do string match.
9324                    if (strings == null) {
9325                        strings = new ArrayList<String>();
9326                    }
9327                    strings.add(name);
9328                    all = false;
9329                }
9330            }
9331        }
9332
9333        int build(String[] args, int opti) {
9334            for (; opti<args.length; opti++) {
9335                String name = args[opti];
9336                if ("--".equals(name)) {
9337                    return opti+1;
9338                }
9339                build(name);
9340            }
9341            return opti;
9342        }
9343
9344        boolean match(Object object, ComponentName comp) {
9345            if (all) {
9346                return true;
9347            }
9348            if (components != null) {
9349                for (int i=0; i<components.size(); i++) {
9350                    if (components.get(i).equals(comp)) {
9351                        return true;
9352                    }
9353                }
9354            }
9355            if (objects != null) {
9356                for (int i=0; i<objects.size(); i++) {
9357                    if (System.identityHashCode(object) == objects.get(i)) {
9358                        return true;
9359                    }
9360                }
9361            }
9362            if (strings != null) {
9363                String flat = comp.flattenToString();
9364                for (int i=0; i<strings.size(); i++) {
9365                    if (flat.contains(strings.get(i))) {
9366                        return true;
9367                    }
9368                }
9369            }
9370            return false;
9371        }
9372    }
9373
9374    /**
9375     * There are three things that cmd can be:
9376     *  - a flattened component name that matches an existing activity
9377     *  - the cmd arg isn't the flattened component name of an existing activity:
9378     *    dump all activity whose component contains the cmd as a substring
9379     *  - A hex number of the ActivityRecord object instance.
9380     */
9381    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9382            int opti, boolean dumpAll) {
9383        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9384
9385        if ("all".equals(name)) {
9386            synchronized (this) {
9387                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9388                    activities.add(r1);
9389                }
9390            }
9391        } else if ("top".equals(name)) {
9392            synchronized (this) {
9393                final int N = mMainStack.mHistory.size();
9394                if (N > 0) {
9395                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9396                }
9397            }
9398        } else {
9399            ItemMatcher matcher = new ItemMatcher();
9400            matcher.build(name);
9401
9402            synchronized (this) {
9403                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9404                    if (matcher.match(r1, r1.intent.getComponent())) {
9405                        activities.add(r1);
9406                    }
9407                }
9408            }
9409        }
9410
9411        if (activities.size() <= 0) {
9412            return false;
9413        }
9414
9415        String[] newArgs = new String[args.length - opti];
9416        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9417
9418        TaskRecord lastTask = null;
9419        boolean needSep = false;
9420        for (int i=activities.size()-1; i>=0; i--) {
9421            ActivityRecord r = (ActivityRecord)activities.get(i);
9422            if (needSep) {
9423                pw.println();
9424            }
9425            needSep = true;
9426            synchronized (this) {
9427                if (lastTask != r.task) {
9428                    lastTask = r.task;
9429                    pw.print("TASK "); pw.print(lastTask.affinity);
9430                            pw.print(" id="); pw.println(lastTask.taskId);
9431                    if (dumpAll) {
9432                        lastTask.dump(pw, "  ");
9433                    }
9434                }
9435            }
9436            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9437        }
9438        return true;
9439    }
9440
9441    /**
9442     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9443     * there is a thread associated with the activity.
9444     */
9445    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9446            final ActivityRecord r, String[] args, boolean dumpAll) {
9447        String innerPrefix = prefix + "  ";
9448        synchronized (this) {
9449            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9450                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9451                    pw.print(" pid=");
9452                    if (r.app != null) pw.println(r.app.pid);
9453                    else pw.println("(not running)");
9454            if (dumpAll) {
9455                r.dump(pw, innerPrefix);
9456            }
9457        }
9458        if (r.app != null && r.app.thread != null) {
9459            // flush anything that is already in the PrintWriter since the thread is going
9460            // to write to the file descriptor directly
9461            pw.flush();
9462            try {
9463                TransferPipe tp = new TransferPipe();
9464                try {
9465                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9466                            r.appToken, innerPrefix, args);
9467                    tp.go(fd);
9468                } finally {
9469                    tp.kill();
9470                }
9471            } catch (IOException e) {
9472                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9473            } catch (RemoteException e) {
9474                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9475            }
9476        }
9477    }
9478
9479    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9480            int opti, boolean dumpAll, String dumpPackage) {
9481        boolean needSep = false;
9482        boolean onlyHistory = false;
9483
9484        if ("history".equals(dumpPackage)) {
9485            onlyHistory = true;
9486            dumpPackage = null;
9487        }
9488
9489        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9490        if (!onlyHistory && dumpAll) {
9491            if (mRegisteredReceivers.size() > 0) {
9492                boolean printed = false;
9493                Iterator it = mRegisteredReceivers.values().iterator();
9494                while (it.hasNext()) {
9495                    ReceiverList r = (ReceiverList)it.next();
9496                    if (dumpPackage != null && (r.app == null ||
9497                            !dumpPackage.equals(r.app.info.packageName))) {
9498                        continue;
9499                    }
9500                    if (!printed) {
9501                        pw.println("  Registered Receivers:");
9502                        needSep = true;
9503                        printed = true;
9504                    }
9505                    pw.print("  * "); pw.println(r);
9506                    r.dump(pw, "    ");
9507                }
9508            }
9509
9510            if (mReceiverResolver.dump(pw, needSep ?
9511                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9512                    "    ", dumpPackage, false)) {
9513                needSep = true;
9514            }
9515        }
9516
9517        for (BroadcastQueue q : mBroadcastQueues) {
9518            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9519        }
9520
9521        needSep = true;
9522
9523        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9524            if (needSep) {
9525                pw.println();
9526            }
9527            needSep = true;
9528            pw.println("  Sticky broadcasts:");
9529            StringBuilder sb = new StringBuilder(128);
9530            for (Map.Entry<String, ArrayList<Intent>> ent
9531                    : mStickyBroadcasts.entrySet()) {
9532                pw.print("  * Sticky action "); pw.print(ent.getKey());
9533                if (dumpAll) {
9534                    pw.println(":");
9535                    ArrayList<Intent> intents = ent.getValue();
9536                    final int N = intents.size();
9537                    for (int i=0; i<N; i++) {
9538                        sb.setLength(0);
9539                        sb.append("    Intent: ");
9540                        intents.get(i).toShortString(sb, false, true, false, false);
9541                        pw.println(sb.toString());
9542                        Bundle bundle = intents.get(i).getExtras();
9543                        if (bundle != null) {
9544                            pw.print("      ");
9545                            pw.println(bundle.toString());
9546                        }
9547                    }
9548                } else {
9549                    pw.println("");
9550                }
9551            }
9552            needSep = true;
9553        }
9554
9555        if (!onlyHistory && dumpAll) {
9556            pw.println();
9557            for (BroadcastQueue queue : mBroadcastQueues) {
9558                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9559                        + queue.mBroadcastsScheduled);
9560            }
9561            pw.println("  mHandler:");
9562            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9563            needSep = true;
9564        }
9565
9566        return needSep;
9567    }
9568
9569    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9570            int opti, boolean dumpAll, String dumpPackage) {
9571        boolean needSep = true;
9572
9573        ItemMatcher matcher = new ItemMatcher();
9574        matcher.build(args, opti);
9575
9576        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9577
9578        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9579
9580        if (mLaunchingProviders.size() > 0) {
9581            boolean printed = false;
9582            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9583                ContentProviderRecord r = mLaunchingProviders.get(i);
9584                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9585                    continue;
9586                }
9587                if (!printed) {
9588                    if (needSep) pw.println(" ");
9589                    needSep = true;
9590                    pw.println("  Launching content providers:");
9591                    printed = true;
9592                }
9593                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9594                        pw.println(r);
9595            }
9596        }
9597
9598        if (mGrantedUriPermissions.size() > 0) {
9599            if (needSep) pw.println();
9600            needSep = true;
9601            pw.println("Granted Uri Permissions:");
9602            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9603                int uid = mGrantedUriPermissions.keyAt(i);
9604                HashMap<Uri, UriPermission> perms
9605                        = mGrantedUriPermissions.valueAt(i);
9606                pw.print("  * UID "); pw.print(uid);
9607                        pw.println(" holds:");
9608                for (UriPermission perm : perms.values()) {
9609                    pw.print("    "); pw.println(perm);
9610                    if (dumpAll) {
9611                        perm.dump(pw, "      ");
9612                    }
9613                }
9614            }
9615            needSep = true;
9616        }
9617
9618        return needSep;
9619    }
9620
9621    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9622            int opti, boolean dumpAll, String dumpPackage) {
9623        boolean needSep = false;
9624
9625        if (mIntentSenderRecords.size() > 0) {
9626            boolean printed = false;
9627            Iterator<WeakReference<PendingIntentRecord>> it
9628                    = mIntentSenderRecords.values().iterator();
9629            while (it.hasNext()) {
9630                WeakReference<PendingIntentRecord> ref = it.next();
9631                PendingIntentRecord rec = ref != null ? ref.get(): null;
9632                if (dumpPackage != null && (rec == null
9633                        || !dumpPackage.equals(rec.key.packageName))) {
9634                    continue;
9635                }
9636                if (!printed) {
9637                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9638                    printed = true;
9639                }
9640                needSep = true;
9641                if (rec != null) {
9642                    pw.print("  * "); pw.println(rec);
9643                    if (dumpAll) {
9644                        rec.dump(pw, "    ");
9645                    }
9646                } else {
9647                    pw.print("  * "); pw.println(ref);
9648                }
9649            }
9650        }
9651
9652        return needSep;
9653    }
9654
9655    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9656            String prefix, String label, boolean complete, boolean brief, boolean client,
9657            String dumpPackage) {
9658        TaskRecord lastTask = null;
9659        boolean needNL = false;
9660        final String innerPrefix = prefix + "      ";
9661        final String[] args = new String[0];
9662        for (int i=list.size()-1; i>=0; i--) {
9663            final ActivityRecord r = (ActivityRecord)list.get(i);
9664            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9665                continue;
9666            }
9667            final boolean full = !brief && (complete || !r.isInHistory());
9668            if (needNL) {
9669                pw.println(" ");
9670                needNL = false;
9671            }
9672            if (lastTask != r.task) {
9673                lastTask = r.task;
9674                pw.print(prefix);
9675                pw.print(full ? "* " : "  ");
9676                pw.println(lastTask);
9677                if (full) {
9678                    lastTask.dump(pw, prefix + "  ");
9679                } else if (complete) {
9680                    // Complete + brief == give a summary.  Isn't that obvious?!?
9681                    if (lastTask.intent != null) {
9682                        pw.print(prefix); pw.print("  ");
9683                                pw.println(lastTask.intent.toInsecureStringWithClip());
9684                    }
9685                }
9686            }
9687            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9688            pw.print(" #"); pw.print(i); pw.print(": ");
9689            pw.println(r);
9690            if (full) {
9691                r.dump(pw, innerPrefix);
9692            } else if (complete) {
9693                // Complete + brief == give a summary.  Isn't that obvious?!?
9694                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9695                if (r.app != null) {
9696                    pw.print(innerPrefix); pw.println(r.app);
9697                }
9698            }
9699            if (client && r.app != null && r.app.thread != null) {
9700                // flush anything that is already in the PrintWriter since the thread is going
9701                // to write to the file descriptor directly
9702                pw.flush();
9703                try {
9704                    TransferPipe tp = new TransferPipe();
9705                    try {
9706                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9707                                r.appToken, innerPrefix, args);
9708                        // Short timeout, since blocking here can
9709                        // deadlock with the application.
9710                        tp.go(fd, 2000);
9711                    } finally {
9712                        tp.kill();
9713                    }
9714                } catch (IOException e) {
9715                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9716                } catch (RemoteException e) {
9717                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9718                }
9719                needNL = true;
9720            }
9721        }
9722    }
9723
9724    private static String buildOomTag(String prefix, String space, int val, int base) {
9725        if (val == base) {
9726            if (space == null) return prefix;
9727            return prefix + "  ";
9728        }
9729        return prefix + "+" + Integer.toString(val-base);
9730    }
9731
9732    private static final int dumpProcessList(PrintWriter pw,
9733            ActivityManagerService service, List list,
9734            String prefix, String normalLabel, String persistentLabel,
9735            String dumpPackage) {
9736        int numPers = 0;
9737        final int N = list.size()-1;
9738        for (int i=N; i>=0; i--) {
9739            ProcessRecord r = (ProcessRecord)list.get(i);
9740            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9741                continue;
9742            }
9743            pw.println(String.format("%s%s #%2d: %s",
9744                    prefix, (r.persistent ? persistentLabel : normalLabel),
9745                    i, r.toString()));
9746            if (r.persistent) {
9747                numPers++;
9748            }
9749        }
9750        return numPers;
9751    }
9752
9753    private static final boolean dumpProcessOomList(PrintWriter pw,
9754            ActivityManagerService service, List<ProcessRecord> origList,
9755            String prefix, String normalLabel, String persistentLabel,
9756            boolean inclDetails, String dumpPackage) {
9757
9758        ArrayList<Pair<ProcessRecord, Integer>> list
9759                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9760        for (int i=0; i<origList.size(); i++) {
9761            ProcessRecord r = origList.get(i);
9762            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9763                continue;
9764            }
9765            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9766        }
9767
9768        if (list.size() <= 0) {
9769            return false;
9770        }
9771
9772        Comparator<Pair<ProcessRecord, Integer>> comparator
9773                = new Comparator<Pair<ProcessRecord, Integer>>() {
9774            @Override
9775            public int compare(Pair<ProcessRecord, Integer> object1,
9776                    Pair<ProcessRecord, Integer> object2) {
9777                if (object1.first.setAdj != object2.first.setAdj) {
9778                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9779                }
9780                if (object1.second.intValue() != object2.second.intValue()) {
9781                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9782                }
9783                return 0;
9784            }
9785        };
9786
9787        Collections.sort(list, comparator);
9788
9789        final long curRealtime = SystemClock.elapsedRealtime();
9790        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9791        final long curUptime = SystemClock.uptimeMillis();
9792        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9793
9794        for (int i=list.size()-1; i>=0; i--) {
9795            ProcessRecord r = list.get(i).first;
9796            String oomAdj;
9797            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9798                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9799            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9800                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9801            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9802                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9803            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9804                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9805            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9806                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9807            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9808                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9809            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9810                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9811            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9812                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9813            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9814                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9815            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9816                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9817            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9818                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9819            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9820                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9821            } else {
9822                oomAdj = Integer.toString(r.setAdj);
9823            }
9824            String schedGroup;
9825            switch (r.setSchedGroup) {
9826                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9827                    schedGroup = "B";
9828                    break;
9829                case Process.THREAD_GROUP_DEFAULT:
9830                    schedGroup = "F";
9831                    break;
9832                default:
9833                    schedGroup = Integer.toString(r.setSchedGroup);
9834                    break;
9835            }
9836            String foreground;
9837            if (r.foregroundActivities) {
9838                foreground = "A";
9839            } else if (r.foregroundServices) {
9840                foreground = "S";
9841            } else {
9842                foreground = " ";
9843            }
9844            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9845                    prefix, (r.persistent ? persistentLabel : normalLabel),
9846                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9847                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9848            if (r.adjSource != null || r.adjTarget != null) {
9849                pw.print(prefix);
9850                pw.print("    ");
9851                if (r.adjTarget instanceof ComponentName) {
9852                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9853                } else if (r.adjTarget != null) {
9854                    pw.print(r.adjTarget.toString());
9855                } else {
9856                    pw.print("{null}");
9857                }
9858                pw.print("<=");
9859                if (r.adjSource instanceof ProcessRecord) {
9860                    pw.print("Proc{");
9861                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9862                    pw.println("}");
9863                } else if (r.adjSource != null) {
9864                    pw.println(r.adjSource.toString());
9865                } else {
9866                    pw.println("{null}");
9867                }
9868            }
9869            if (inclDetails) {
9870                pw.print(prefix);
9871                pw.print("    ");
9872                pw.print("oom: max="); pw.print(r.maxAdj);
9873                pw.print(" hidden="); pw.print(r.hiddenAdj);
9874                pw.print(" empty="); pw.print(r.emptyAdj);
9875                pw.print(" curRaw="); pw.print(r.curRawAdj);
9876                pw.print(" setRaw="); pw.print(r.setRawAdj);
9877                pw.print(" cur="); pw.print(r.curAdj);
9878                pw.print(" set="); pw.println(r.setAdj);
9879                pw.print(prefix);
9880                pw.print("    ");
9881                pw.print("keeping="); pw.print(r.keeping);
9882                pw.print(" hidden="); pw.print(r.hidden);
9883                pw.print(" empty="); pw.print(r.empty);
9884                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
9885
9886                if (!r.keeping) {
9887                    if (r.lastWakeTime != 0) {
9888                        long wtime;
9889                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9890                        synchronized (stats) {
9891                            wtime = stats.getProcessWakeTime(r.info.uid,
9892                                    r.pid, curRealtime);
9893                        }
9894                        long timeUsed = wtime - r.lastWakeTime;
9895                        pw.print(prefix);
9896                        pw.print("    ");
9897                        pw.print("keep awake over ");
9898                        TimeUtils.formatDuration(realtimeSince, pw);
9899                        pw.print(" used ");
9900                        TimeUtils.formatDuration(timeUsed, pw);
9901                        pw.print(" (");
9902                        pw.print((timeUsed*100)/realtimeSince);
9903                        pw.println("%)");
9904                    }
9905                    if (r.lastCpuTime != 0) {
9906                        long timeUsed = r.curCpuTime - r.lastCpuTime;
9907                        pw.print(prefix);
9908                        pw.print("    ");
9909                        pw.print("run cpu over ");
9910                        TimeUtils.formatDuration(uptimeSince, pw);
9911                        pw.print(" used ");
9912                        TimeUtils.formatDuration(timeUsed, pw);
9913                        pw.print(" (");
9914                        pw.print((timeUsed*100)/uptimeSince);
9915                        pw.println("%)");
9916                    }
9917                }
9918            }
9919        }
9920        return true;
9921    }
9922
9923    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
9924        ArrayList<ProcessRecord> procs;
9925        synchronized (this) {
9926            if (args != null && args.length > start
9927                    && args[start].charAt(0) != '-') {
9928                procs = new ArrayList<ProcessRecord>();
9929                int pid = -1;
9930                try {
9931                    pid = Integer.parseInt(args[start]);
9932                } catch (NumberFormatException e) {
9933
9934                }
9935                for (int i=mLruProcesses.size()-1; i>=0; i--) {
9936                    ProcessRecord proc = mLruProcesses.get(i);
9937                    if (proc.pid == pid) {
9938                        procs.add(proc);
9939                    } else if (proc.processName.equals(args[start])) {
9940                        procs.add(proc);
9941                    }
9942                }
9943                if (procs.size() <= 0) {
9944                    pw.println("No process found for: " + args[start]);
9945                    return null;
9946                }
9947            } else {
9948                procs = new ArrayList<ProcessRecord>(mLruProcesses);
9949            }
9950        }
9951        return procs;
9952    }
9953
9954    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9955            PrintWriter pw, String[] args) {
9956        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9957        if (procs == null) {
9958            return;
9959        }
9960
9961        long uptime = SystemClock.uptimeMillis();
9962        long realtime = SystemClock.elapsedRealtime();
9963        pw.println("Applications Graphics Acceleration Info:");
9964        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9965
9966        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9967            ProcessRecord r = procs.get(i);
9968            if (r.thread != null) {
9969                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9970                pw.flush();
9971                try {
9972                    TransferPipe tp = new TransferPipe();
9973                    try {
9974                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9975                        tp.go(fd);
9976                    } finally {
9977                        tp.kill();
9978                    }
9979                } catch (IOException e) {
9980                    pw.println("Failure while dumping the app: " + r);
9981                    pw.flush();
9982                } catch (RemoteException e) {
9983                    pw.println("Got a RemoteException while dumping the app " + r);
9984                    pw.flush();
9985                }
9986            }
9987        }
9988    }
9989
9990    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
9991        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9992        if (procs == null) {
9993            return;
9994        }
9995
9996        pw.println("Applications Database Info:");
9997
9998        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9999            ProcessRecord r = procs.get(i);
10000            if (r.thread != null) {
10001                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10002                pw.flush();
10003                try {
10004                    TransferPipe tp = new TransferPipe();
10005                    try {
10006                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10007                        tp.go(fd);
10008                    } finally {
10009                        tp.kill();
10010                    }
10011                } catch (IOException e) {
10012                    pw.println("Failure while dumping the app: " + r);
10013                    pw.flush();
10014                } catch (RemoteException e) {
10015                    pw.println("Got a RemoteException while dumping the app " + r);
10016                    pw.flush();
10017                }
10018            }
10019        }
10020    }
10021
10022    final static class MemItem {
10023        final String label;
10024        final String shortLabel;
10025        final long pss;
10026        final int id;
10027        ArrayList<MemItem> subitems;
10028
10029        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10030            label = _label;
10031            shortLabel = _shortLabel;
10032            pss = _pss;
10033            id = _id;
10034        }
10035    }
10036
10037    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10038            boolean sort) {
10039        if (sort) {
10040            Collections.sort(items, new Comparator<MemItem>() {
10041                @Override
10042                public int compare(MemItem lhs, MemItem rhs) {
10043                    if (lhs.pss < rhs.pss) {
10044                        return 1;
10045                    } else if (lhs.pss > rhs.pss) {
10046                        return -1;
10047                    }
10048                    return 0;
10049                }
10050            });
10051        }
10052
10053        for (int i=0; i<items.size(); i++) {
10054            MemItem mi = items.get(i);
10055            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10056            if (mi.subitems != null) {
10057                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10058            }
10059        }
10060    }
10061
10062    // These are in KB.
10063    static final long[] DUMP_MEM_BUCKETS = new long[] {
10064        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10065        120*1024, 160*1024, 200*1024,
10066        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10067        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10068    };
10069
10070    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10071            boolean stackLike) {
10072        int start = label.lastIndexOf('.');
10073        if (start >= 0) start++;
10074        else start = 0;
10075        int end = label.length();
10076        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10077            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10078                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10079                out.append(bucket);
10080                out.append(stackLike ? "MB." : "MB ");
10081                out.append(label, start, end);
10082                return;
10083            }
10084        }
10085        out.append(memKB/1024);
10086        out.append(stackLike ? "MB." : "MB ");
10087        out.append(label, start, end);
10088    }
10089
10090    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10091            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10092            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10093            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10094            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10095    };
10096    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10097            "System", "Persistent", "Foreground",
10098            "Visible", "Perceptible", "Heavy Weight",
10099            "Backup", "A Services", "Home", "Previous",
10100            "B Services", "Background"
10101    };
10102
10103    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10104            PrintWriter pw, String prefix, String[] args, boolean brief,
10105            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10106        boolean dumpAll = false;
10107        boolean oomOnly = false;
10108
10109        int opti = 0;
10110        while (opti < args.length) {
10111            String opt = args[opti];
10112            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10113                break;
10114            }
10115            opti++;
10116            if ("-a".equals(opt)) {
10117                dumpAll = true;
10118            } else if ("--oom".equals(opt)) {
10119                oomOnly = true;
10120            } else if ("-h".equals(opt)) {
10121                pw.println("meminfo dump options: [-a] [--oom] [process]");
10122                pw.println("  -a: include all available information for each process.");
10123                pw.println("  --oom: only show processes organized by oom adj.");
10124                pw.println("If [process] is specified it can be the name or ");
10125                pw.println("pid of a specific process to dump.");
10126                return;
10127            } else {
10128                pw.println("Unknown argument: " + opt + "; use -h for help");
10129            }
10130        }
10131
10132        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10133        if (procs == null) {
10134            return;
10135        }
10136
10137        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10138        long uptime = SystemClock.uptimeMillis();
10139        long realtime = SystemClock.elapsedRealtime();
10140
10141        if (procs.size() == 1 || isCheckinRequest) {
10142            dumpAll = true;
10143        }
10144
10145        if (isCheckinRequest) {
10146            // short checkin version
10147            pw.println(uptime + "," + realtime);
10148            pw.flush();
10149        } else {
10150            pw.println("Applications Memory Usage (kB):");
10151            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10152        }
10153
10154        String[] innerArgs = new String[args.length-opti];
10155        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10156
10157        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10158        long nativePss=0, dalvikPss=0, otherPss=0;
10159        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10160
10161        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10162        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10163                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10164
10165        long totalPss = 0;
10166
10167        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10168            ProcessRecord r = procs.get(i);
10169            if (r.thread != null) {
10170                if (!isCheckinRequest && dumpAll) {
10171                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10172                    pw.flush();
10173                }
10174                Debug.MemoryInfo mi = null;
10175                if (dumpAll) {
10176                    try {
10177                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10178                    } catch (RemoteException e) {
10179                        if (!isCheckinRequest) {
10180                            pw.println("Got RemoteException!");
10181                            pw.flush();
10182                        }
10183                    }
10184                } else {
10185                    mi = new Debug.MemoryInfo();
10186                    Debug.getMemoryInfo(r.pid, mi);
10187                }
10188
10189                if (!isCheckinRequest && mi != null) {
10190                    long myTotalPss = mi.getTotalPss();
10191                    totalPss += myTotalPss;
10192                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10193                            r.processName, myTotalPss, 0);
10194                    procMems.add(pssItem);
10195
10196                    nativePss += mi.nativePss;
10197                    dalvikPss += mi.dalvikPss;
10198                    otherPss += mi.otherPss;
10199                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10200                        long mem = mi.getOtherPss(j);
10201                        miscPss[j] += mem;
10202                        otherPss -= mem;
10203                    }
10204
10205                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10206                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10207                                || oomIndex == (oomPss.length-1)) {
10208                            oomPss[oomIndex] += myTotalPss;
10209                            if (oomProcs[oomIndex] == null) {
10210                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10211                            }
10212                            oomProcs[oomIndex].add(pssItem);
10213                            break;
10214                        }
10215                    }
10216                }
10217            }
10218        }
10219
10220        if (!isCheckinRequest && procs.size() > 1) {
10221            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10222
10223            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10224            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10225            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10226            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10227                String label = Debug.MemoryInfo.getOtherLabel(j);
10228                catMems.add(new MemItem(label, label, miscPss[j], j));
10229            }
10230
10231            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10232            for (int j=0; j<oomPss.length; j++) {
10233                if (oomPss[j] != 0) {
10234                    String label = DUMP_MEM_OOM_LABEL[j];
10235                    MemItem item = new MemItem(label, label, oomPss[j],
10236                            DUMP_MEM_OOM_ADJ[j]);
10237                    item.subitems = oomProcs[j];
10238                    oomMems.add(item);
10239                }
10240            }
10241
10242            if (outTag != null || outStack != null) {
10243                if (outTag != null) {
10244                    appendMemBucket(outTag, totalPss, "total", false);
10245                }
10246                if (outStack != null) {
10247                    appendMemBucket(outStack, totalPss, "total", true);
10248                }
10249                boolean firstLine = true;
10250                for (int i=0; i<oomMems.size(); i++) {
10251                    MemItem miCat = oomMems.get(i);
10252                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10253                        continue;
10254                    }
10255                    if (miCat.id < ProcessList.SERVICE_ADJ
10256                            || miCat.id == ProcessList.HOME_APP_ADJ
10257                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10258                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10259                            outTag.append(" / ");
10260                        }
10261                        if (outStack != null) {
10262                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10263                                if (firstLine) {
10264                                    outStack.append(":");
10265                                    firstLine = false;
10266                                }
10267                                outStack.append("\n\t at ");
10268                            } else {
10269                                outStack.append("$");
10270                            }
10271                        }
10272                        for (int j=0; j<miCat.subitems.size(); j++) {
10273                            MemItem mi = miCat.subitems.get(j);
10274                            if (j > 0) {
10275                                if (outTag != null) {
10276                                    outTag.append(" ");
10277                                }
10278                                if (outStack != null) {
10279                                    outStack.append("$");
10280                                }
10281                            }
10282                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10283                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10284                            }
10285                            if (outStack != null) {
10286                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10287                            }
10288                        }
10289                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10290                            outStack.append("(");
10291                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10292                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10293                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10294                                    outStack.append(":");
10295                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10296                                }
10297                            }
10298                            outStack.append(")");
10299                        }
10300                    }
10301                }
10302            }
10303
10304            if (!brief && !oomOnly) {
10305                pw.println();
10306                pw.println("Total PSS by process:");
10307                dumpMemItems(pw, "  ", procMems, true);
10308                pw.println();
10309            }
10310            pw.println("Total PSS by OOM adjustment:");
10311            dumpMemItems(pw, "  ", oomMems, false);
10312            if (!oomOnly) {
10313                PrintWriter out = categoryPw != null ? categoryPw : pw;
10314                out.println();
10315                out.println("Total PSS by category:");
10316                dumpMemItems(out, "  ", catMems, true);
10317            }
10318            pw.println();
10319            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10320            final int[] SINGLE_LONG_FORMAT = new int[] {
10321                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10322            };
10323            long[] longOut = new long[1];
10324            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10325                    SINGLE_LONG_FORMAT, null, longOut, null);
10326            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10327            longOut[0] = 0;
10328            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10329                    SINGLE_LONG_FORMAT, null, longOut, null);
10330            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10331            longOut[0] = 0;
10332            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10333                    SINGLE_LONG_FORMAT, null, longOut, null);
10334            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10335            longOut[0] = 0;
10336            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10337                    SINGLE_LONG_FORMAT, null, longOut, null);
10338            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10339            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10340                    pw.print(shared); pw.println(" kB");
10341            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10342                    pw.print(voltile); pw.println(" kB volatile");
10343        }
10344    }
10345
10346    /**
10347     * Searches array of arguments for the specified string
10348     * @param args array of argument strings
10349     * @param value value to search for
10350     * @return true if the value is contained in the array
10351     */
10352    private static boolean scanArgs(String[] args, String value) {
10353        if (args != null) {
10354            for (String arg : args) {
10355                if (value.equals(arg)) {
10356                    return true;
10357                }
10358            }
10359        }
10360        return false;
10361    }
10362
10363    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10364            ContentProviderRecord cpr, boolean always) {
10365        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10366
10367        if (!inLaunching || always) {
10368            synchronized (cpr) {
10369                cpr.launchingApp = null;
10370                cpr.notifyAll();
10371            }
10372            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10373            String names[] = cpr.info.authority.split(";");
10374            for (int j = 0; j < names.length; j++) {
10375                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10376            }
10377        }
10378
10379        for (int i=0; i<cpr.connections.size(); i++) {
10380            ContentProviderConnection conn = cpr.connections.get(i);
10381            if (conn.waiting) {
10382                // If this connection is waiting for the provider, then we don't
10383                // need to mess with its process unless we are always removing
10384                // or for some reason the provider is not currently launching.
10385                if (inLaunching && !always) {
10386                    continue;
10387                }
10388            }
10389            ProcessRecord capp = conn.client;
10390            conn.dead = true;
10391            if (conn.stableCount > 0) {
10392                if (!capp.persistent && capp.thread != null
10393                        && capp.pid != 0
10394                        && capp.pid != MY_PID) {
10395                    Slog.i(TAG, "Kill " + capp.processName
10396                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10397                            + " in dying process " + (proc != null ? proc.processName : "??"));
10398                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10399                            capp.processName, capp.setAdj, "dying provider "
10400                                    + cpr.name.toShortString());
10401                    Process.killProcessQuiet(capp.pid);
10402                }
10403            } else if (capp.thread != null && conn.provider.provider != null) {
10404                try {
10405                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10406                } catch (RemoteException e) {
10407                }
10408                // In the protocol here, we don't expect the client to correctly
10409                // clean up this connection, we'll just remove it.
10410                cpr.connections.remove(i);
10411                conn.client.conProviders.remove(conn);
10412            }
10413        }
10414
10415        if (inLaunching && always) {
10416            mLaunchingProviders.remove(cpr);
10417        }
10418        return inLaunching;
10419    }
10420
10421    /**
10422     * Main code for cleaning up a process when it has gone away.  This is
10423     * called both as a result of the process dying, or directly when stopping
10424     * a process when running in single process mode.
10425     */
10426    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10427            boolean restarting, boolean allowRestart, int index) {
10428        if (index >= 0) {
10429            mLruProcesses.remove(index);
10430        }
10431
10432        mProcessesToGc.remove(app);
10433
10434        // Dismiss any open dialogs.
10435        if (app.crashDialog != null) {
10436            app.crashDialog.dismiss();
10437            app.crashDialog = null;
10438        }
10439        if (app.anrDialog != null) {
10440            app.anrDialog.dismiss();
10441            app.anrDialog = null;
10442        }
10443        if (app.waitDialog != null) {
10444            app.waitDialog.dismiss();
10445            app.waitDialog = null;
10446        }
10447
10448        app.crashing = false;
10449        app.notResponding = false;
10450
10451        app.resetPackageList();
10452        app.unlinkDeathRecipient();
10453        app.thread = null;
10454        app.forcingToForeground = null;
10455        app.foregroundServices = false;
10456        app.foregroundActivities = false;
10457        app.hasShownUi = false;
10458        app.hasAboveClient = false;
10459
10460        mServices.killServicesLocked(app, allowRestart);
10461
10462        boolean restart = false;
10463
10464        // Remove published content providers.
10465        if (!app.pubProviders.isEmpty()) {
10466            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10467            while (it.hasNext()) {
10468                ContentProviderRecord cpr = it.next();
10469
10470                final boolean always = app.bad || !allowRestart;
10471                if (removeDyingProviderLocked(app, cpr, always) || always) {
10472                    // We left the provider in the launching list, need to
10473                    // restart it.
10474                    restart = true;
10475                }
10476
10477                cpr.provider = null;
10478                cpr.proc = null;
10479            }
10480            app.pubProviders.clear();
10481        }
10482
10483        // Take care of any launching providers waiting for this process.
10484        if (checkAppInLaunchingProvidersLocked(app, false)) {
10485            restart = true;
10486        }
10487
10488        // Unregister from connected content providers.
10489        if (!app.conProviders.isEmpty()) {
10490            for (int i=0; i<app.conProviders.size(); i++) {
10491                ContentProviderConnection conn = app.conProviders.get(i);
10492                conn.provider.connections.remove(conn);
10493            }
10494            app.conProviders.clear();
10495        }
10496
10497        // At this point there may be remaining entries in mLaunchingProviders
10498        // where we were the only one waiting, so they are no longer of use.
10499        // Look for these and clean up if found.
10500        // XXX Commented out for now.  Trying to figure out a way to reproduce
10501        // the actual situation to identify what is actually going on.
10502        if (false) {
10503            for (int i=0; i<mLaunchingProviders.size(); i++) {
10504                ContentProviderRecord cpr = (ContentProviderRecord)
10505                        mLaunchingProviders.get(i);
10506                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10507                    synchronized (cpr) {
10508                        cpr.launchingApp = null;
10509                        cpr.notifyAll();
10510                    }
10511                }
10512            }
10513        }
10514
10515        skipCurrentReceiverLocked(app);
10516
10517        // Unregister any receivers.
10518        if (app.receivers.size() > 0) {
10519            Iterator<ReceiverList> it = app.receivers.iterator();
10520            while (it.hasNext()) {
10521                removeReceiverLocked(it.next());
10522            }
10523            app.receivers.clear();
10524        }
10525
10526        // If the app is undergoing backup, tell the backup manager about it
10527        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10528            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10529            try {
10530                IBackupManager bm = IBackupManager.Stub.asInterface(
10531                        ServiceManager.getService(Context.BACKUP_SERVICE));
10532                bm.agentDisconnected(app.info.packageName);
10533            } catch (RemoteException e) {
10534                // can't happen; backup manager is local
10535            }
10536        }
10537
10538        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10539            ProcessChangeItem item = mPendingProcessChanges.get(i);
10540            if (item.pid == app.pid) {
10541                mPendingProcessChanges.remove(i);
10542                mAvailProcessChanges.add(item);
10543            }
10544        }
10545        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10546
10547        // If the caller is restarting this app, then leave it in its
10548        // current lists and let the caller take care of it.
10549        if (restarting) {
10550            return;
10551        }
10552
10553        if (!app.persistent || app.isolated) {
10554            if (DEBUG_PROCESSES) Slog.v(TAG,
10555                    "Removing non-persistent process during cleanup: " + app);
10556            mProcessNames.remove(app.processName, app.uid);
10557            mIsolatedProcesses.remove(app.uid);
10558            if (mHeavyWeightProcess == app) {
10559                mHeavyWeightProcess = null;
10560                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10561            }
10562        } else if (!app.removed) {
10563            // This app is persistent, so we need to keep its record around.
10564            // If it is not already on the pending app list, add it there
10565            // and start a new process for it.
10566            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10567                mPersistentStartingProcesses.add(app);
10568                restart = true;
10569            }
10570        }
10571        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10572                "Clean-up removing on hold: " + app);
10573        mProcessesOnHold.remove(app);
10574
10575        if (app == mHomeProcess) {
10576            mHomeProcess = null;
10577        }
10578        if (app == mPreviousProcess) {
10579            mPreviousProcess = null;
10580        }
10581
10582        if (restart && !app.isolated) {
10583            // We have components that still need to be running in the
10584            // process, so re-launch it.
10585            mProcessNames.put(app.processName, app.uid, app);
10586            startProcessLocked(app, "restart", app.processName);
10587        } else if (app.pid > 0 && app.pid != MY_PID) {
10588            // Goodbye!
10589            synchronized (mPidsSelfLocked) {
10590                mPidsSelfLocked.remove(app.pid);
10591                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10592            }
10593            app.setPid(0);
10594        }
10595    }
10596
10597    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10598        // Look through the content providers we are waiting to have launched,
10599        // and if any run in this process then either schedule a restart of
10600        // the process or kill the client waiting for it if this process has
10601        // gone bad.
10602        int NL = mLaunchingProviders.size();
10603        boolean restart = false;
10604        for (int i=0; i<NL; i++) {
10605            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10606            if (cpr.launchingApp == app) {
10607                if (!alwaysBad && !app.bad) {
10608                    restart = true;
10609                } else {
10610                    removeDyingProviderLocked(app, cpr, true);
10611                    NL = mLaunchingProviders.size();
10612                }
10613            }
10614        }
10615        return restart;
10616    }
10617
10618    // =========================================================
10619    // SERVICES
10620    // =========================================================
10621
10622    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10623            int flags) {
10624        enforceNotIsolatedCaller("getServices");
10625        synchronized (this) {
10626            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10627        }
10628    }
10629
10630    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10631        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10632        synchronized (this) {
10633            return mServices.getRunningServiceControlPanelLocked(name);
10634        }
10635    }
10636
10637    public ComponentName startService(IApplicationThread caller, Intent service,
10638            String resolvedType, int userId) {
10639        enforceNotIsolatedCaller("startService");
10640        // Refuse possible leaked file descriptors
10641        if (service != null && service.hasFileDescriptors() == true) {
10642            throw new IllegalArgumentException("File descriptors passed in Intent");
10643        }
10644
10645        if (DEBUG_SERVICE)
10646            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10647        synchronized(this) {
10648            final int callingPid = Binder.getCallingPid();
10649            final int callingUid = Binder.getCallingUid();
10650            checkValidCaller(callingUid, userId);
10651            final long origId = Binder.clearCallingIdentity();
10652            ComponentName res = mServices.startServiceLocked(caller, service,
10653                    resolvedType, callingPid, callingUid, userId);
10654            Binder.restoreCallingIdentity(origId);
10655            return res;
10656        }
10657    }
10658
10659    ComponentName startServiceInPackage(int uid,
10660            Intent service, String resolvedType) {
10661        synchronized(this) {
10662            if (DEBUG_SERVICE)
10663                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10664            final long origId = Binder.clearCallingIdentity();
10665            ComponentName res = mServices.startServiceLocked(null, service,
10666                    resolvedType, -1, uid, UserHandle.getUserId(uid));
10667            Binder.restoreCallingIdentity(origId);
10668            return res;
10669        }
10670    }
10671
10672    public int stopService(IApplicationThread caller, Intent service,
10673            String resolvedType, int userId) {
10674        enforceNotIsolatedCaller("stopService");
10675        // Refuse possible leaked file descriptors
10676        if (service != null && service.hasFileDescriptors() == true) {
10677            throw new IllegalArgumentException("File descriptors passed in Intent");
10678        }
10679
10680        checkValidCaller(Binder.getCallingUid(), userId);
10681
10682        synchronized(this) {
10683            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10684        }
10685    }
10686
10687    public IBinder peekService(Intent service, String resolvedType) {
10688        enforceNotIsolatedCaller("peekService");
10689        // Refuse possible leaked file descriptors
10690        if (service != null && service.hasFileDescriptors() == true) {
10691            throw new IllegalArgumentException("File descriptors passed in Intent");
10692        }
10693        synchronized(this) {
10694            return mServices.peekServiceLocked(service, resolvedType);
10695        }
10696    }
10697
10698    public boolean stopServiceToken(ComponentName className, IBinder token,
10699            int startId) {
10700        synchronized(this) {
10701            return mServices.stopServiceTokenLocked(className, token, startId);
10702        }
10703    }
10704
10705    public void setServiceForeground(ComponentName className, IBinder token,
10706            int id, Notification notification, boolean removeNotification) {
10707        synchronized(this) {
10708            mServices.setServiceForegroundLocked(className, token, id, notification,
10709                    removeNotification);
10710        }
10711    }
10712
10713    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10714            String className, int flags) {
10715        boolean result = false;
10716        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10717            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10718                if (ActivityManager.checkUidPermission(
10719                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10720                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10721                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10722                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10723                            + " requests FLAG_SINGLE_USER, but app does not hold "
10724                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10725                    Slog.w(TAG, msg);
10726                    throw new SecurityException(msg);
10727                }
10728                result = true;
10729            }
10730        } else if (componentProcessName == aInfo.packageName) {
10731            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10732        } else if ("system".equals(componentProcessName)) {
10733            result = true;
10734        }
10735        if (DEBUG_MU) {
10736            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10737                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10738        }
10739        return result;
10740    }
10741
10742    public int bindService(IApplicationThread caller, IBinder token,
10743            Intent service, String resolvedType,
10744            IServiceConnection connection, int flags, int userId) {
10745        enforceNotIsolatedCaller("bindService");
10746        // Refuse possible leaked file descriptors
10747        if (service != null && service.hasFileDescriptors() == true) {
10748            throw new IllegalArgumentException("File descriptors passed in Intent");
10749        }
10750
10751        if (userId != UserHandle.getCallingUserId()) {
10752            // Requesting a different user, make sure that they have permission
10753            if (checkComponentPermission(
10754                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10755                    Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
10756                    == PackageManager.PERMISSION_GRANTED) {
10757                // Translate to the current user id, if caller wasn't aware
10758                if (userId == UserHandle.USER_CURRENT) {
10759                    userId = mCurrentUserId;
10760                }
10761            } else {
10762                String msg = "Permission Denial: Request to bindService as user " + userId
10763                        + " but is calling from user " + UserHandle.getCallingUserId()
10764                        + "; this requires "
10765                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
10766                Slog.w(TAG, msg);
10767                throw new SecurityException(msg);
10768            }
10769        }
10770
10771        synchronized(this) {
10772            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10773                    connection, flags, userId);
10774        }
10775    }
10776
10777    public boolean unbindService(IServiceConnection connection) {
10778        synchronized (this) {
10779            return mServices.unbindServiceLocked(connection);
10780        }
10781    }
10782
10783    public void publishService(IBinder token, Intent intent, IBinder service) {
10784        // Refuse possible leaked file descriptors
10785        if (intent != null && intent.hasFileDescriptors() == true) {
10786            throw new IllegalArgumentException("File descriptors passed in Intent");
10787        }
10788
10789        synchronized(this) {
10790            if (!(token instanceof ServiceRecord)) {
10791                throw new IllegalArgumentException("Invalid service token");
10792            }
10793            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
10794        }
10795    }
10796
10797    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10798        // Refuse possible leaked file descriptors
10799        if (intent != null && intent.hasFileDescriptors() == true) {
10800            throw new IllegalArgumentException("File descriptors passed in Intent");
10801        }
10802
10803        synchronized(this) {
10804            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
10805        }
10806    }
10807
10808    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10809        synchronized(this) {
10810            if (!(token instanceof ServiceRecord)) {
10811                throw new IllegalArgumentException("Invalid service token");
10812            }
10813            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
10814        }
10815    }
10816
10817    // =========================================================
10818    // BACKUP AND RESTORE
10819    // =========================================================
10820
10821    // Cause the target app to be launched if necessary and its backup agent
10822    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10823    // activity manager to announce its creation.
10824    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10825        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10826        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10827
10828        synchronized(this) {
10829            // !!! TODO: currently no check here that we're already bound
10830            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10831            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10832            synchronized (stats) {
10833                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10834            }
10835
10836            // Backup agent is now in use, its package can't be stopped.
10837            try {
10838                AppGlobals.getPackageManager().setPackageStoppedState(
10839                        app.packageName, false, UserHandle.getUserId(app.uid));
10840            } catch (RemoteException e) {
10841            } catch (IllegalArgumentException e) {
10842                Slog.w(TAG, "Failed trying to unstop package "
10843                        + app.packageName + ": " + e);
10844            }
10845
10846            BackupRecord r = new BackupRecord(ss, app, backupMode);
10847            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10848                    ? new ComponentName(app.packageName, app.backupAgentName)
10849                    : new ComponentName("android", "FullBackupAgent");
10850            // startProcessLocked() returns existing proc's record if it's already running
10851            ProcessRecord proc = startProcessLocked(app.processName, app,
10852                    false, 0, "backup", hostingName, false, false);
10853            if (proc == null) {
10854                Slog.e(TAG, "Unable to start backup agent process " + r);
10855                return false;
10856            }
10857
10858            r.app = proc;
10859            mBackupTarget = r;
10860            mBackupAppName = app.packageName;
10861
10862            // Try not to kill the process during backup
10863            updateOomAdjLocked(proc);
10864
10865            // If the process is already attached, schedule the creation of the backup agent now.
10866            // If it is not yet live, this will be done when it attaches to the framework.
10867            if (proc.thread != null) {
10868                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
10869                try {
10870                    proc.thread.scheduleCreateBackupAgent(app,
10871                            compatibilityInfoForPackageLocked(app), backupMode);
10872                } catch (RemoteException e) {
10873                    // Will time out on the backup manager side
10874                }
10875            } else {
10876                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
10877            }
10878            // Invariants: at this point, the target app process exists and the application
10879            // is either already running or in the process of coming up.  mBackupTarget and
10880            // mBackupAppName describe the app, so that when it binds back to the AM we
10881            // know that it's scheduled for a backup-agent operation.
10882        }
10883
10884        return true;
10885    }
10886
10887    // A backup agent has just come up
10888    public void backupAgentCreated(String agentPackageName, IBinder agent) {
10889        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
10890                + " = " + agent);
10891
10892        synchronized(this) {
10893            if (!agentPackageName.equals(mBackupAppName)) {
10894                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
10895                return;
10896            }
10897        }
10898
10899        long oldIdent = Binder.clearCallingIdentity();
10900        try {
10901            IBackupManager bm = IBackupManager.Stub.asInterface(
10902                    ServiceManager.getService(Context.BACKUP_SERVICE));
10903            bm.agentConnected(agentPackageName, agent);
10904        } catch (RemoteException e) {
10905            // can't happen; the backup manager service is local
10906        } catch (Exception e) {
10907            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10908            e.printStackTrace();
10909        } finally {
10910            Binder.restoreCallingIdentity(oldIdent);
10911        }
10912    }
10913
10914    // done with this agent
10915    public void unbindBackupAgent(ApplicationInfo appInfo) {
10916        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
10917        if (appInfo == null) {
10918            Slog.w(TAG, "unbind backup agent for null app");
10919            return;
10920        }
10921
10922        synchronized(this) {
10923            if (mBackupAppName == null) {
10924                Slog.w(TAG, "Unbinding backup agent with no active backup");
10925                return;
10926            }
10927
10928            if (!mBackupAppName.equals(appInfo.packageName)) {
10929                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
10930                return;
10931            }
10932
10933            ProcessRecord proc = mBackupTarget.app;
10934            mBackupTarget = null;
10935            mBackupAppName = null;
10936
10937            // Not backing this app up any more; reset its OOM adjustment
10938            updateOomAdjLocked(proc);
10939
10940            // If the app crashed during backup, 'thread' will be null here
10941            if (proc.thread != null) {
10942                try {
10943                    proc.thread.scheduleDestroyBackupAgent(appInfo,
10944                            compatibilityInfoForPackageLocked(appInfo));
10945                } catch (Exception e) {
10946                    Slog.e(TAG, "Exception when unbinding backup agent:");
10947                    e.printStackTrace();
10948                }
10949            }
10950        }
10951    }
10952    // =========================================================
10953    // BROADCASTS
10954    // =========================================================
10955
10956    private final List getStickiesLocked(String action, IntentFilter filter,
10957            List cur) {
10958        final ContentResolver resolver = mContext.getContentResolver();
10959        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10960        if (list == null) {
10961            return cur;
10962        }
10963        int N = list.size();
10964        for (int i=0; i<N; i++) {
10965            Intent intent = list.get(i);
10966            if (filter.match(resolver, intent, true, TAG) >= 0) {
10967                if (cur == null) {
10968                    cur = new ArrayList<Intent>();
10969                }
10970                cur.add(intent);
10971            }
10972        }
10973        return cur;
10974    }
10975
10976    boolean isPendingBroadcastProcessLocked(int pid) {
10977        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
10978                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
10979    }
10980
10981    void skipPendingBroadcastLocked(int pid) {
10982            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
10983            for (BroadcastQueue queue : mBroadcastQueues) {
10984                queue.skipPendingBroadcastLocked(pid);
10985            }
10986    }
10987
10988    // The app just attached; send any pending broadcasts that it should receive
10989    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
10990        boolean didSomething = false;
10991        for (BroadcastQueue queue : mBroadcastQueues) {
10992            didSomething |= queue.sendPendingBroadcastsLocked(app);
10993        }
10994        return didSomething;
10995    }
10996
10997    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
10998            IIntentReceiver receiver, IntentFilter filter, String permission) {
10999        enforceNotIsolatedCaller("registerReceiver");
11000        int callingUid;
11001        synchronized(this) {
11002            ProcessRecord callerApp = null;
11003            if (caller != null) {
11004                callerApp = getRecordForAppLocked(caller);
11005                if (callerApp == null) {
11006                    throw new SecurityException(
11007                            "Unable to find app for caller " + caller
11008                            + " (pid=" + Binder.getCallingPid()
11009                            + ") when registering receiver " + receiver);
11010                }
11011                if (callerApp.info.uid != Process.SYSTEM_UID &&
11012                        !callerApp.pkgList.contains(callerPackage)) {
11013                    throw new SecurityException("Given caller package " + callerPackage
11014                            + " is not running in process " + callerApp);
11015                }
11016                callingUid = callerApp.info.uid;
11017            } else {
11018                callerPackage = null;
11019                callingUid = Binder.getCallingUid();
11020            }
11021
11022            List allSticky = null;
11023
11024            // Look for any matching sticky broadcasts...
11025            Iterator actions = filter.actionsIterator();
11026            if (actions != null) {
11027                while (actions.hasNext()) {
11028                    String action = (String)actions.next();
11029                    allSticky = getStickiesLocked(action, filter, allSticky);
11030                }
11031            } else {
11032                allSticky = getStickiesLocked(null, filter, allSticky);
11033            }
11034
11035            // The first sticky in the list is returned directly back to
11036            // the client.
11037            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11038
11039            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11040                    + ": " + sticky);
11041
11042            if (receiver == null) {
11043                return sticky;
11044            }
11045
11046            ReceiverList rl
11047                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11048            if (rl == null) {
11049                rl = new ReceiverList(this, callerApp,
11050                        Binder.getCallingPid(),
11051                        Binder.getCallingUid(), receiver);
11052                if (rl.app != null) {
11053                    rl.app.receivers.add(rl);
11054                } else {
11055                    try {
11056                        receiver.asBinder().linkToDeath(rl, 0);
11057                    } catch (RemoteException e) {
11058                        return sticky;
11059                    }
11060                    rl.linkedToDeath = true;
11061                }
11062                mRegisteredReceivers.put(receiver.asBinder(), rl);
11063            }
11064            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11065                    permission, callingUid);
11066            rl.add(bf);
11067            if (!bf.debugCheck()) {
11068                Slog.w(TAG, "==> For Dynamic broadast");
11069            }
11070            mReceiverResolver.addFilter(bf);
11071
11072            // Enqueue broadcasts for all existing stickies that match
11073            // this filter.
11074            if (allSticky != null) {
11075                ArrayList receivers = new ArrayList();
11076                receivers.add(bf);
11077
11078                int N = allSticky.size();
11079                for (int i=0; i<N; i++) {
11080                    Intent intent = (Intent)allSticky.get(i);
11081                    BroadcastQueue queue = broadcastQueueForIntent(intent);
11082                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11083                            null, -1, -1, null, receivers, null, 0, null, null,
11084                            false, true, true, -1);
11085                    queue.enqueueParallelBroadcastLocked(r);
11086                    queue.scheduleBroadcastsLocked();
11087                }
11088            }
11089
11090            return sticky;
11091        }
11092    }
11093
11094    public void unregisterReceiver(IIntentReceiver receiver) {
11095        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11096
11097        final long origId = Binder.clearCallingIdentity();
11098        try {
11099            boolean doTrim = false;
11100
11101            synchronized(this) {
11102                ReceiverList rl
11103                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11104                if (rl != null) {
11105                    if (rl.curBroadcast != null) {
11106                        BroadcastRecord r = rl.curBroadcast;
11107                        final boolean doNext = finishReceiverLocked(
11108                                receiver.asBinder(), r.resultCode, r.resultData,
11109                                r.resultExtras, r.resultAbort, true);
11110                        if (doNext) {
11111                            doTrim = true;
11112                            r.queue.processNextBroadcast(false);
11113                        }
11114                    }
11115
11116                    if (rl.app != null) {
11117                        rl.app.receivers.remove(rl);
11118                    }
11119                    removeReceiverLocked(rl);
11120                    if (rl.linkedToDeath) {
11121                        rl.linkedToDeath = false;
11122                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11123                    }
11124                }
11125            }
11126
11127            // If we actually concluded any broadcasts, we might now be able
11128            // to trim the recipients' apps from our working set
11129            if (doTrim) {
11130                trimApplications();
11131                return;
11132            }
11133
11134        } finally {
11135            Binder.restoreCallingIdentity(origId);
11136        }
11137    }
11138
11139    void removeReceiverLocked(ReceiverList rl) {
11140        mRegisteredReceivers.remove(rl.receiver.asBinder());
11141        int N = rl.size();
11142        for (int i=0; i<N; i++) {
11143            mReceiverResolver.removeFilter(rl.get(i));
11144        }
11145    }
11146
11147    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11148        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11149            ProcessRecord r = mLruProcesses.get(i);
11150            if (r.thread != null) {
11151                try {
11152                    r.thread.dispatchPackageBroadcast(cmd, packages);
11153                } catch (RemoteException ex) {
11154                }
11155            }
11156        }
11157    }
11158
11159    private final int broadcastIntentLocked(ProcessRecord callerApp,
11160            String callerPackage, Intent intent, String resolvedType,
11161            IIntentReceiver resultTo, int resultCode, String resultData,
11162            Bundle map, String requiredPermission,
11163            boolean ordered, boolean sticky, int callingPid, int callingUid,
11164            int userId) {
11165        intent = new Intent(intent);
11166
11167        // By default broadcasts do not go to stopped apps.
11168        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11169
11170        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11171            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11172            + " ordered=" + ordered + " userid=" + userId);
11173        if ((resultTo != null) && !ordered) {
11174            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11175        }
11176
11177        // If the caller is trying to send this broadcast to a different
11178        // user, verify that is allowed.
11179        if (UserHandle.getUserId(callingUid) != userId) {
11180            if (checkComponentPermission(
11181                    android.Manifest.permission.INTERACT_ACROSS_USERS,
11182                    callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED
11183                    && checkComponentPermission(
11184                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
11185                            callingPid, callingUid, -1, true)
11186                            != PackageManager.PERMISSION_GRANTED) {
11187                String msg = "Permission Denial: " + intent.getAction()
11188                        + " broadcast from " + callerPackage
11189                        + " asks to send as user " + userId
11190                        + " but is calling from user " + UserHandle.getUserId(callingUid)
11191                        + "; this requires "
11192                        + android.Manifest.permission.INTERACT_ACROSS_USERS;
11193                Slog.w(TAG, msg);
11194                throw new SecurityException(msg);
11195            } else {
11196                if (userId == UserHandle.USER_CURRENT) {
11197                    userId = mCurrentUserId;
11198                }
11199            }
11200        }
11201
11202        // Make sure that the user who is receiving this broadcast is started
11203        // If not, we will just skip it.
11204        if (mStartedUsers.get(userId) == null) {
11205            Slog.w(TAG, "Skipping broadcast of " + intent
11206                    + ": user " + userId + " is stopped");
11207            return ActivityManager.BROADCAST_SUCCESS;
11208        }
11209
11210        // Handle special intents: if this broadcast is from the package
11211        // manager about a package being removed, we need to remove all of
11212        // its activities from the history stack.
11213        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11214                intent.getAction());
11215        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11216                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11217                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11218                || uidRemoved) {
11219            if (checkComponentPermission(
11220                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11221                    callingPid, callingUid, -1, true)
11222                    == PackageManager.PERMISSION_GRANTED) {
11223                if (uidRemoved) {
11224                    final Bundle intentExtras = intent.getExtras();
11225                    final int uid = intentExtras != null
11226                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11227                    if (uid >= 0) {
11228                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11229                        synchronized (bs) {
11230                            bs.removeUidStatsLocked(uid);
11231                        }
11232                    }
11233                } else {
11234                    // If resources are unvailble just force stop all
11235                    // those packages and flush the attribute cache as well.
11236                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11237                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11238                        if (list != null && (list.length > 0)) {
11239                            for (String pkg : list) {
11240                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11241                            }
11242                            sendPackageBroadcastLocked(
11243                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
11244                        }
11245                    } else {
11246                        Uri data = intent.getData();
11247                        String ssp;
11248                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11249                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11250                                forceStopPackageLocked(ssp,
11251                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11252                                        false, userId);
11253                            }
11254                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11255                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11256                                        new String[] {ssp});
11257                            }
11258                        }
11259                    }
11260                }
11261            } else {
11262                String msg = "Permission Denial: " + intent.getAction()
11263                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11264                        + ", uid=" + callingUid + ")"
11265                        + " requires "
11266                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11267                Slog.w(TAG, msg);
11268                throw new SecurityException(msg);
11269            }
11270
11271        // Special case for adding a package: by default turn on compatibility
11272        // mode.
11273        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11274            Uri data = intent.getData();
11275            String ssp;
11276            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11277                mCompatModePackages.handlePackageAddedLocked(ssp,
11278                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11279            }
11280        }
11281
11282        /*
11283         * If this is the time zone changed action, queue up a message that will reset the timezone
11284         * of all currently running processes. This message will get queued up before the broadcast
11285         * happens.
11286         */
11287        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11288            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11289        }
11290
11291        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11292            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11293        }
11294
11295        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11296            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11297            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11298        }
11299
11300        /*
11301         * Prevent non-system code (defined here to be non-persistent
11302         * processes) from sending protected broadcasts.
11303         */
11304        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11305            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11306            callingUid == 0) {
11307            // Always okay.
11308        } else if (callerApp == null || !callerApp.persistent) {
11309            try {
11310                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11311                        intent.getAction())) {
11312                    String msg = "Permission Denial: not allowed to send broadcast "
11313                            + intent.getAction() + " from pid="
11314                            + callingPid + ", uid=" + callingUid;
11315                    Slog.w(TAG, msg);
11316                    throw new SecurityException(msg);
11317                }
11318            } catch (RemoteException e) {
11319                Slog.w(TAG, "Remote exception", e);
11320                return ActivityManager.BROADCAST_SUCCESS;
11321            }
11322        }
11323
11324        // Add to the sticky list if requested.
11325        if (sticky) {
11326            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11327                    callingPid, callingUid)
11328                    != PackageManager.PERMISSION_GRANTED) {
11329                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11330                        + callingPid + ", uid=" + callingUid
11331                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11332                Slog.w(TAG, msg);
11333                throw new SecurityException(msg);
11334            }
11335            if (requiredPermission != null) {
11336                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11337                        + " and enforce permission " + requiredPermission);
11338                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11339            }
11340            if (intent.getComponent() != null) {
11341                throw new SecurityException(
11342                        "Sticky broadcasts can't target a specific component");
11343            }
11344            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11345            if (list == null) {
11346                list = new ArrayList<Intent>();
11347                mStickyBroadcasts.put(intent.getAction(), list);
11348            }
11349            int N = list.size();
11350            int i;
11351            for (i=0; i<N; i++) {
11352                if (intent.filterEquals(list.get(i))) {
11353                    // This sticky already exists, replace it.
11354                    list.set(i, new Intent(intent));
11355                    break;
11356                }
11357            }
11358            if (i >= N) {
11359                list.add(new Intent(intent));
11360            }
11361        }
11362
11363        // Figure out who all will receive this broadcast.
11364        List receivers = null;
11365        List<BroadcastFilter> registeredReceivers = null;
11366        try {
11367            // Need to resolve the intent to interested receivers...
11368            if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11369                     == 0) {
11370                receivers = AppGlobals.getPackageManager().queryIntentReceivers(
11371                        intent, resolvedType, STOCK_PM_FLAGS, userId);
11372            }
11373            if (intent.getComponent() == null) {
11374                registeredReceivers = mReceiverResolver.queryIntent(intent,
11375                        resolvedType, false, userId);
11376            }
11377        } catch (RemoteException ex) {
11378            // pm is in same process, this will never happen.
11379        }
11380
11381        final boolean replacePending =
11382                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11383
11384        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11385                + " replacePending=" + replacePending);
11386
11387        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11388        if (!ordered && NR > 0) {
11389            // If we are not serializing this broadcast, then send the
11390            // registered receivers separately so they don't wait for the
11391            // components to be launched.
11392            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11393            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11394                    callerPackage, callingPid, callingUid, requiredPermission,
11395                    registeredReceivers, resultTo, resultCode, resultData, map,
11396                    ordered, sticky, false, userId);
11397            if (DEBUG_BROADCAST) Slog.v(
11398                    TAG, "Enqueueing parallel broadcast " + r);
11399            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11400            if (!replaced) {
11401                queue.enqueueParallelBroadcastLocked(r);
11402                queue.scheduleBroadcastsLocked();
11403            }
11404            registeredReceivers = null;
11405            NR = 0;
11406        }
11407
11408        // Merge into one list.
11409        int ir = 0;
11410        if (receivers != null) {
11411            // A special case for PACKAGE_ADDED: do not allow the package
11412            // being added to see this broadcast.  This prevents them from
11413            // using this as a back door to get run as soon as they are
11414            // installed.  Maybe in the future we want to have a special install
11415            // broadcast or such for apps, but we'd like to deliberately make
11416            // this decision.
11417            String skipPackages[] = null;
11418            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11419                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11420                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11421                Uri data = intent.getData();
11422                if (data != null) {
11423                    String pkgName = data.getSchemeSpecificPart();
11424                    if (pkgName != null) {
11425                        skipPackages = new String[] { pkgName };
11426                    }
11427                }
11428            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11429                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11430            }
11431            if (skipPackages != null && (skipPackages.length > 0)) {
11432                for (String skipPackage : skipPackages) {
11433                    if (skipPackage != null) {
11434                        int NT = receivers.size();
11435                        for (int it=0; it<NT; it++) {
11436                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11437                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11438                                receivers.remove(it);
11439                                it--;
11440                                NT--;
11441                            }
11442                        }
11443                    }
11444                }
11445            }
11446
11447            int NT = receivers != null ? receivers.size() : 0;
11448            int it = 0;
11449            ResolveInfo curt = null;
11450            BroadcastFilter curr = null;
11451            while (it < NT && ir < NR) {
11452                if (curt == null) {
11453                    curt = (ResolveInfo)receivers.get(it);
11454                }
11455                if (curr == null) {
11456                    curr = registeredReceivers.get(ir);
11457                }
11458                if (curr.getPriority() >= curt.priority) {
11459                    // Insert this broadcast record into the final list.
11460                    receivers.add(it, curr);
11461                    ir++;
11462                    curr = null;
11463                    it++;
11464                    NT++;
11465                } else {
11466                    // Skip to the next ResolveInfo in the final list.
11467                    it++;
11468                    curt = null;
11469                }
11470            }
11471        }
11472        while (ir < NR) {
11473            if (receivers == null) {
11474                receivers = new ArrayList();
11475            }
11476            receivers.add(registeredReceivers.get(ir));
11477            ir++;
11478        }
11479
11480        if ((receivers != null && receivers.size() > 0)
11481                || resultTo != null) {
11482            BroadcastQueue queue = broadcastQueueForIntent(intent);
11483            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11484                    callerPackage, callingPid, callingUid, requiredPermission,
11485                    receivers, resultTo, resultCode, resultData, map, ordered,
11486                    sticky, false, userId);
11487            if (DEBUG_BROADCAST) Slog.v(
11488                    TAG, "Enqueueing ordered broadcast " + r
11489                    + ": prev had " + queue.mOrderedBroadcasts.size());
11490            if (DEBUG_BROADCAST) {
11491                int seq = r.intent.getIntExtra("seq", -1);
11492                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11493            }
11494            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11495            if (!replaced) {
11496                queue.enqueueOrderedBroadcastLocked(r);
11497                queue.scheduleBroadcastsLocked();
11498            }
11499        }
11500
11501        return ActivityManager.BROADCAST_SUCCESS;
11502    }
11503
11504    final Intent verifyBroadcastLocked(Intent intent) {
11505        // Refuse possible leaked file descriptors
11506        if (intent != null && intent.hasFileDescriptors() == true) {
11507            throw new IllegalArgumentException("File descriptors passed in Intent");
11508        }
11509
11510        int flags = intent.getFlags();
11511
11512        if (!mProcessesReady) {
11513            // if the caller really truly claims to know what they're doing, go
11514            // ahead and allow the broadcast without launching any receivers
11515            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11516                intent = new Intent(intent);
11517                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11518            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11519                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11520                        + " before boot completion");
11521                throw new IllegalStateException("Cannot broadcast before boot completed");
11522            }
11523        }
11524
11525        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11526            throw new IllegalArgumentException(
11527                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11528        }
11529
11530        return intent;
11531    }
11532
11533    public final int broadcastIntent(IApplicationThread caller,
11534            Intent intent, String resolvedType, IIntentReceiver resultTo,
11535            int resultCode, String resultData, Bundle map,
11536            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11537        enforceNotIsolatedCaller("broadcastIntent");
11538        synchronized(this) {
11539            intent = verifyBroadcastLocked(intent);
11540
11541            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11542            final int callingPid = Binder.getCallingPid();
11543            final int callingUid = Binder.getCallingUid();
11544            final long origId = Binder.clearCallingIdentity();
11545            int res = broadcastIntentLocked(callerApp,
11546                    callerApp != null ? callerApp.info.packageName : null,
11547                    intent, resolvedType, resultTo,
11548                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11549                    callingPid, callingUid, userId);
11550            Binder.restoreCallingIdentity(origId);
11551            return res;
11552        }
11553    }
11554
11555    int broadcastIntentInPackage(String packageName, int uid,
11556            Intent intent, String resolvedType, IIntentReceiver resultTo,
11557            int resultCode, String resultData, Bundle map,
11558            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11559        synchronized(this) {
11560            intent = verifyBroadcastLocked(intent);
11561
11562            final long origId = Binder.clearCallingIdentity();
11563            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11564                    resultTo, resultCode, resultData, map, requiredPermission,
11565                    serialized, sticky, -1, uid, userId);
11566            Binder.restoreCallingIdentity(origId);
11567            return res;
11568        }
11569    }
11570
11571    // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
11572    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11573        // Refuse possible leaked file descriptors
11574        if (intent != null && intent.hasFileDescriptors() == true) {
11575            throw new IllegalArgumentException("File descriptors passed in Intent");
11576        }
11577
11578        synchronized(this) {
11579            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11580                    != PackageManager.PERMISSION_GRANTED) {
11581                String msg = "Permission Denial: unbroadcastIntent() from pid="
11582                        + Binder.getCallingPid()
11583                        + ", uid=" + Binder.getCallingUid()
11584                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11585                Slog.w(TAG, msg);
11586                throw new SecurityException(msg);
11587            }
11588            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11589            if (list != null) {
11590                int N = list.size();
11591                int i;
11592                for (i=0; i<N; i++) {
11593                    if (intent.filterEquals(list.get(i))) {
11594                        list.remove(i);
11595                        break;
11596                    }
11597                }
11598            }
11599        }
11600    }
11601
11602    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11603            String resultData, Bundle resultExtras, boolean resultAbort,
11604            boolean explicit) {
11605        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11606        if (r == null) {
11607            Slog.w(TAG, "finishReceiver called but not found on queue");
11608            return false;
11609        }
11610
11611        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11612                explicit);
11613    }
11614
11615    public void finishReceiver(IBinder who, int resultCode, String resultData,
11616            Bundle resultExtras, boolean resultAbort) {
11617        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11618
11619        // Refuse possible leaked file descriptors
11620        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11621            throw new IllegalArgumentException("File descriptors passed in Bundle");
11622        }
11623
11624        final long origId = Binder.clearCallingIdentity();
11625        try {
11626            boolean doNext = false;
11627            BroadcastRecord r = null;
11628
11629            synchronized(this) {
11630                r = broadcastRecordForReceiverLocked(who);
11631                if (r != null) {
11632                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11633                        resultData, resultExtras, resultAbort, true);
11634                }
11635            }
11636
11637            if (doNext) {
11638                r.queue.processNextBroadcast(false);
11639            }
11640            trimApplications();
11641        } finally {
11642            Binder.restoreCallingIdentity(origId);
11643        }
11644    }
11645
11646    // =========================================================
11647    // INSTRUMENTATION
11648    // =========================================================
11649
11650    public boolean startInstrumentation(ComponentName className,
11651            String profileFile, int flags, Bundle arguments,
11652            IInstrumentationWatcher watcher) {
11653        enforceNotIsolatedCaller("startInstrumentation");
11654        // Refuse possible leaked file descriptors
11655        if (arguments != null && arguments.hasFileDescriptors()) {
11656            throw new IllegalArgumentException("File descriptors passed in Bundle");
11657        }
11658
11659        synchronized(this) {
11660            InstrumentationInfo ii = null;
11661            ApplicationInfo ai = null;
11662            try {
11663                ii = mContext.getPackageManager().getInstrumentationInfo(
11664                    className, STOCK_PM_FLAGS);
11665                ai = mContext.getPackageManager().getApplicationInfo(
11666                        ii.targetPackage, STOCK_PM_FLAGS);
11667            } catch (PackageManager.NameNotFoundException e) {
11668            }
11669            if (ii == null) {
11670                reportStartInstrumentationFailure(watcher, className,
11671                        "Unable to find instrumentation info for: " + className);
11672                return false;
11673            }
11674            if (ai == null) {
11675                reportStartInstrumentationFailure(watcher, className,
11676                        "Unable to find instrumentation target package: " + ii.targetPackage);
11677                return false;
11678            }
11679
11680            int match = mContext.getPackageManager().checkSignatures(
11681                    ii.targetPackage, ii.packageName);
11682            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11683                String msg = "Permission Denial: starting instrumentation "
11684                        + className + " from pid="
11685                        + Binder.getCallingPid()
11686                        + ", uid=" + Binder.getCallingPid()
11687                        + " not allowed because package " + ii.packageName
11688                        + " does not have a signature matching the target "
11689                        + ii.targetPackage;
11690                reportStartInstrumentationFailure(watcher, className, msg);
11691                throw new SecurityException(msg);
11692            }
11693
11694            int userId = UserHandle.getCallingUserId();
11695            final long origId = Binder.clearCallingIdentity();
11696            // Instrumentation can kill and relaunch even persistent processes
11697            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
11698            ProcessRecord app = addAppLocked(ai, false);
11699            app.instrumentationClass = className;
11700            app.instrumentationInfo = ai;
11701            app.instrumentationProfileFile = profileFile;
11702            app.instrumentationArguments = arguments;
11703            app.instrumentationWatcher = watcher;
11704            app.instrumentationResultClass = className;
11705            Binder.restoreCallingIdentity(origId);
11706        }
11707
11708        return true;
11709    }
11710
11711    /**
11712     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11713     * error to the logs, but if somebody is watching, send the report there too.  This enables
11714     * the "am" command to report errors with more information.
11715     *
11716     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11717     * @param cn The component name of the instrumentation.
11718     * @param report The error report.
11719     */
11720    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11721            ComponentName cn, String report) {
11722        Slog.w(TAG, report);
11723        try {
11724            if (watcher != null) {
11725                Bundle results = new Bundle();
11726                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11727                results.putString("Error", report);
11728                watcher.instrumentationStatus(cn, -1, results);
11729            }
11730        } catch (RemoteException e) {
11731            Slog.w(TAG, e);
11732        }
11733    }
11734
11735    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11736        if (app.instrumentationWatcher != null) {
11737            try {
11738                // NOTE:  IInstrumentationWatcher *must* be oneway here
11739                app.instrumentationWatcher.instrumentationFinished(
11740                    app.instrumentationClass,
11741                    resultCode,
11742                    results);
11743            } catch (RemoteException e) {
11744            }
11745        }
11746        app.instrumentationWatcher = null;
11747        app.instrumentationClass = null;
11748        app.instrumentationInfo = null;
11749        app.instrumentationProfileFile = null;
11750        app.instrumentationArguments = null;
11751
11752        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
11753    }
11754
11755    public void finishInstrumentation(IApplicationThread target,
11756            int resultCode, Bundle results) {
11757        int userId = UserHandle.getCallingUserId();
11758        // Refuse possible leaked file descriptors
11759        if (results != null && results.hasFileDescriptors()) {
11760            throw new IllegalArgumentException("File descriptors passed in Intent");
11761        }
11762
11763        synchronized(this) {
11764            ProcessRecord app = getRecordForAppLocked(target);
11765            if (app == null) {
11766                Slog.w(TAG, "finishInstrumentation: no app for " + target);
11767                return;
11768            }
11769            final long origId = Binder.clearCallingIdentity();
11770            finishInstrumentationLocked(app, resultCode, results);
11771            Binder.restoreCallingIdentity(origId);
11772        }
11773    }
11774
11775    // =========================================================
11776    // CONFIGURATION
11777    // =========================================================
11778
11779    public ConfigurationInfo getDeviceConfigurationInfo() {
11780        ConfigurationInfo config = new ConfigurationInfo();
11781        synchronized (this) {
11782            config.reqTouchScreen = mConfiguration.touchscreen;
11783            config.reqKeyboardType = mConfiguration.keyboard;
11784            config.reqNavigation = mConfiguration.navigation;
11785            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11786                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
11787                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11788            }
11789            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11790                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
11791                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11792            }
11793            config.reqGlEsVersion = GL_ES_VERSION;
11794        }
11795        return config;
11796    }
11797
11798    public Configuration getConfiguration() {
11799        Configuration ci;
11800        synchronized(this) {
11801            ci = new Configuration(mConfiguration);
11802        }
11803        return ci;
11804    }
11805
11806    public void updatePersistentConfiguration(Configuration values) {
11807        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11808                "updateConfiguration()");
11809        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
11810                "updateConfiguration()");
11811        if (values == null) {
11812            throw new NullPointerException("Configuration must not be null");
11813        }
11814
11815        synchronized(this) {
11816            final long origId = Binder.clearCallingIdentity();
11817            updateConfigurationLocked(values, null, true, false);
11818            Binder.restoreCallingIdentity(origId);
11819        }
11820    }
11821
11822    public void updateConfiguration(Configuration values) {
11823        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11824                "updateConfiguration()");
11825
11826        synchronized(this) {
11827            if (values == null && mWindowManager != null) {
11828                // sentinel: fetch the current configuration from the window manager
11829                values = mWindowManager.computeNewConfiguration();
11830            }
11831
11832            if (mWindowManager != null) {
11833                mProcessList.applyDisplaySize(mWindowManager);
11834            }
11835
11836            final long origId = Binder.clearCallingIdentity();
11837            if (values != null) {
11838                Settings.System.clearConfiguration(values);
11839            }
11840            updateConfigurationLocked(values, null, false, false);
11841            Binder.restoreCallingIdentity(origId);
11842        }
11843    }
11844
11845    /**
11846     * Do either or both things: (1) change the current configuration, and (2)
11847     * make sure the given activity is running with the (now) current
11848     * configuration.  Returns true if the activity has been left running, or
11849     * false if <var>starting</var> is being destroyed to match the new
11850     * configuration.
11851     * @param persistent TODO
11852     */
11853    boolean updateConfigurationLocked(Configuration values,
11854            ActivityRecord starting, boolean persistent, boolean initLocale) {
11855        // do nothing if we are headless
11856        if (mHeadless) return true;
11857
11858        int changes = 0;
11859
11860        boolean kept = true;
11861
11862        if (values != null) {
11863            Configuration newConfig = new Configuration(mConfiguration);
11864            changes = newConfig.updateFrom(values);
11865            if (changes != 0) {
11866                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
11867                    Slog.i(TAG, "Updating configuration to: " + values);
11868                }
11869
11870                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
11871
11872                if (values.locale != null && !initLocale) {
11873                    saveLocaleLocked(values.locale,
11874                                     !values.locale.equals(mConfiguration.locale),
11875                                     values.userSetLocale);
11876                }
11877
11878                mConfigurationSeq++;
11879                if (mConfigurationSeq <= 0) {
11880                    mConfigurationSeq = 1;
11881                }
11882                newConfig.seq = mConfigurationSeq;
11883                mConfiguration = newConfig;
11884                Slog.i(TAG, "Config changed: " + newConfig);
11885
11886                final Configuration configCopy = new Configuration(mConfiguration);
11887
11888                // TODO: If our config changes, should we auto dismiss any currently
11889                // showing dialogs?
11890                mShowDialogs = shouldShowDialogs(newConfig);
11891
11892                AttributeCache ac = AttributeCache.instance();
11893                if (ac != null) {
11894                    ac.updateConfiguration(configCopy);
11895                }
11896
11897                // Make sure all resources in our process are updated
11898                // right now, so that anyone who is going to retrieve
11899                // resource values after we return will be sure to get
11900                // the new ones.  This is especially important during
11901                // boot, where the first config change needs to guarantee
11902                // all resources have that config before following boot
11903                // code is executed.
11904                mSystemThread.applyConfigurationToResources(configCopy);
11905
11906                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
11907                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
11908                    msg.obj = new Configuration(configCopy);
11909                    mHandler.sendMessage(msg);
11910                }
11911
11912                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11913                    ProcessRecord app = mLruProcesses.get(i);
11914                    try {
11915                        if (app.thread != null) {
11916                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
11917                                    + app.processName + " new config " + mConfiguration);
11918                            app.thread.scheduleConfigurationChanged(configCopy);
11919                        }
11920                    } catch (Exception e) {
11921                    }
11922                }
11923                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
11924                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11925                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
11926                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
11927                        null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11928                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
11929                    broadcastIntentLocked(null, null,
11930                            new Intent(Intent.ACTION_LOCALE_CHANGED),
11931                            null, null, 0, null, null,
11932                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
11933                }
11934            }
11935        }
11936
11937        if (changes != 0 && starting == null) {
11938            // If the configuration changed, and the caller is not already
11939            // in the process of starting an activity, then find the top
11940            // activity to check if its configuration needs to change.
11941            starting = mMainStack.topRunningActivityLocked(null);
11942        }
11943
11944        if (starting != null) {
11945            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
11946            // And we need to make sure at this point that all other activities
11947            // are made visible with the correct configuration.
11948            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
11949        }
11950
11951        if (values != null && mWindowManager != null) {
11952            mWindowManager.setNewConfiguration(mConfiguration);
11953        }
11954
11955        return kept;
11956    }
11957
11958    /**
11959     * Decide based on the configuration whether we should shouw the ANR,
11960     * crash, etc dialogs.  The idea is that if there is no affordnace to
11961     * press the on-screen buttons, we shouldn't show the dialog.
11962     *
11963     * A thought: SystemUI might also want to get told about this, the Power
11964     * dialog / global actions also might want different behaviors.
11965     */
11966    private static final boolean shouldShowDialogs(Configuration config) {
11967        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
11968                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
11969    }
11970
11971    /**
11972     * Save the locale.  You must be inside a synchronized (this) block.
11973     */
11974    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
11975        if(isDiff) {
11976            SystemProperties.set("user.language", l.getLanguage());
11977            SystemProperties.set("user.region", l.getCountry());
11978        }
11979
11980        if(isPersist) {
11981            SystemProperties.set("persist.sys.language", l.getLanguage());
11982            SystemProperties.set("persist.sys.country", l.getCountry());
11983            SystemProperties.set("persist.sys.localevar", l.getVariant());
11984        }
11985    }
11986
11987    @Override
11988    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
11989        ActivityRecord srec = ActivityRecord.forToken(token);
11990        return srec != null && srec.task.affinity != null &&
11991                srec.task.affinity.equals(destAffinity);
11992    }
11993
11994    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
11995            Intent resultData) {
11996        ComponentName dest = destIntent.getComponent();
11997
11998        synchronized (this) {
11999            ActivityRecord srec = ActivityRecord.forToken(token);
12000            if (srec == null) {
12001                return false;
12002            }
12003            ArrayList<ActivityRecord> history = srec.stack.mHistory;
12004            final int start = history.indexOf(srec);
12005            if (start < 0) {
12006                // Current activity is not in history stack; do nothing.
12007                return false;
12008            }
12009            int finishTo = start - 1;
12010            ActivityRecord parent = null;
12011            boolean foundParentInTask = false;
12012            if (dest != null) {
12013                TaskRecord tr = srec.task;
12014                for (int i = start - 1; i >= 0; i--) {
12015                    ActivityRecord r = history.get(i);
12016                    if (tr != r.task) {
12017                        // Couldn't find parent in the same task; stop at the one above this.
12018                        // (Root of current task; in-app "home" behavior)
12019                        // Always at least finish the current activity.
12020                        finishTo = Math.min(start - 1, i + 1);
12021                        parent = history.get(finishTo);
12022                        break;
12023                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
12024                            r.info.name.equals(dest.getClassName())) {
12025                        finishTo = i;
12026                        parent = r;
12027                        foundParentInTask = true;
12028                        break;
12029                    }
12030                }
12031            }
12032
12033            if (mController != null) {
12034                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12035                if (next != null) {
12036                    // ask watcher if this is allowed
12037                    boolean resumeOK = true;
12038                    try {
12039                        resumeOK = mController.activityResuming(next.packageName);
12040                    } catch (RemoteException e) {
12041                        mController = null;
12042                    }
12043
12044                    if (!resumeOK) {
12045                        return false;
12046                    }
12047                }
12048            }
12049            final long origId = Binder.clearCallingIdentity();
12050            for (int i = start; i > finishTo; i--) {
12051                ActivityRecord r = history.get(i);
12052                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12053                        "navigate-up");
12054                // Only return the supplied result for the first activity finished
12055                resultCode = Activity.RESULT_CANCELED;
12056                resultData = null;
12057            }
12058
12059            if (parent != null && foundParentInTask) {
12060                final int parentLaunchMode = parent.info.launchMode;
12061                final int destIntentFlags = destIntent.getFlags();
12062                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12063                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12064                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12065                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12066                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12067                } else {
12068                    try {
12069                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12070                                destIntent.getComponent(), 0, UserHandle.getCallingUserId());
12071                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12072                                null, aInfo, parent.appToken, null,
12073                                0, -1, parent.launchedFromUid, 0, null, true, null);
12074                        foundParentInTask = res == ActivityManager.START_SUCCESS;
12075                    } catch (RemoteException e) {
12076                        foundParentInTask = false;
12077                    }
12078                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12079                            resultData, "navigate-up");
12080                }
12081            }
12082            Binder.restoreCallingIdentity(origId);
12083            return foundParentInTask;
12084        }
12085    }
12086
12087    public int getLaunchedFromUid(IBinder activityToken) {
12088        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12089        if (srec == null) {
12090            return -1;
12091        }
12092        return srec.launchedFromUid;
12093    }
12094
12095    // =========================================================
12096    // LIFETIME MANAGEMENT
12097    // =========================================================
12098
12099    // Returns which broadcast queue the app is the current [or imminent] receiver
12100    // on, or 'null' if the app is not an active broadcast recipient.
12101    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12102        BroadcastRecord r = app.curReceiver;
12103        if (r != null) {
12104            return r.queue;
12105        }
12106
12107        // It's not the current receiver, but it might be starting up to become one
12108        synchronized (this) {
12109            for (BroadcastQueue queue : mBroadcastQueues) {
12110                r = queue.mPendingBroadcast;
12111                if (r != null && r.curApp == app) {
12112                    // found it; report which queue it's in
12113                    return queue;
12114                }
12115            }
12116        }
12117
12118        return null;
12119    }
12120
12121    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12122            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12123        if (mAdjSeq == app.adjSeq) {
12124            // This adjustment has already been computed.  If we are calling
12125            // from the top, we may have already computed our adjustment with
12126            // an earlier hidden adjustment that isn't really for us... if
12127            // so, use the new hidden adjustment.
12128            if (!recursed && app.hidden) {
12129                app.curAdj = app.curRawAdj = app.nonStoppingAdj =
12130                        app.hasActivities ? hiddenAdj : emptyAdj;
12131            }
12132            return app.curRawAdj;
12133        }
12134
12135        if (app.thread == null) {
12136            app.adjSeq = mAdjSeq;
12137            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12138            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12139        }
12140
12141        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12142        app.adjSource = null;
12143        app.adjTarget = null;
12144        app.empty = false;
12145        app.hidden = false;
12146
12147        final int activitiesSize = app.activities.size();
12148
12149        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12150            // The max adjustment doesn't allow this app to be anything
12151            // below foreground, so it is not worth doing work for it.
12152            app.adjType = "fixed";
12153            app.adjSeq = mAdjSeq;
12154            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12155            app.hasActivities = false;
12156            app.foregroundActivities = false;
12157            app.keeping = true;
12158            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12159            // System process can do UI, and when they do we want to have
12160            // them trim their memory after the user leaves the UI.  To
12161            // facilitate this, here we need to determine whether or not it
12162            // is currently showing UI.
12163            app.systemNoUi = true;
12164            if (app == TOP_APP) {
12165                app.systemNoUi = false;
12166                app.hasActivities = true;
12167            } else if (activitiesSize > 0) {
12168                for (int j = 0; j < activitiesSize; j++) {
12169                    final ActivityRecord r = app.activities.get(j);
12170                    if (r.visible) {
12171                        app.systemNoUi = false;
12172                    }
12173                    if (r.app == app) {
12174                        app.hasActivities = true;
12175                    }
12176                }
12177            }
12178            return (app.curAdj=app.maxAdj);
12179        }
12180
12181        app.keeping = false;
12182        app.systemNoUi = false;
12183        app.hasActivities = false;
12184
12185        // Determine the importance of the process, starting with most
12186        // important to least, and assign an appropriate OOM adjustment.
12187        int adj;
12188        int schedGroup;
12189        boolean foregroundActivities = false;
12190        boolean interesting = false;
12191        BroadcastQueue queue;
12192        if (app == TOP_APP) {
12193            // The last app on the list is the foreground app.
12194            adj = ProcessList.FOREGROUND_APP_ADJ;
12195            schedGroup = Process.THREAD_GROUP_DEFAULT;
12196            app.adjType = "top-activity";
12197            foregroundActivities = true;
12198            interesting = true;
12199            app.hasActivities = true;
12200        } else if (app.instrumentationClass != null) {
12201            // Don't want to kill running instrumentation.
12202            adj = ProcessList.FOREGROUND_APP_ADJ;
12203            schedGroup = Process.THREAD_GROUP_DEFAULT;
12204            app.adjType = "instrumentation";
12205            interesting = true;
12206        } else if ((queue = isReceivingBroadcast(app)) != null) {
12207            // An app that is currently receiving a broadcast also
12208            // counts as being in the foreground for OOM killer purposes.
12209            // It's placed in a sched group based on the nature of the
12210            // broadcast as reflected by which queue it's active in.
12211            adj = ProcessList.FOREGROUND_APP_ADJ;
12212            schedGroup = (queue == mFgBroadcastQueue)
12213                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12214            app.adjType = "broadcast";
12215        } else if (app.executingServices.size() > 0) {
12216            // An app that is currently executing a service callback also
12217            // counts as being in the foreground.
12218            adj = ProcessList.FOREGROUND_APP_ADJ;
12219            schedGroup = Process.THREAD_GROUP_DEFAULT;
12220            app.adjType = "exec-service";
12221        } else {
12222            // Assume process is hidden (has activities); we will correct
12223            // later if this is not the case.
12224            adj = hiddenAdj;
12225            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12226            app.hidden = true;
12227            app.adjType = "bg-activities";
12228        }
12229
12230        boolean hasStoppingActivities = false;
12231
12232        // Examine all activities if not already foreground.
12233        if (!foregroundActivities && activitiesSize > 0) {
12234            for (int j = 0; j < activitiesSize; j++) {
12235                final ActivityRecord r = app.activities.get(j);
12236                if (r.visible) {
12237                    // App has a visible activity; only upgrade adjustment.
12238                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12239                        adj = ProcessList.VISIBLE_APP_ADJ;
12240                        app.adjType = "visible";
12241                    }
12242                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12243                    app.hidden = false;
12244                    app.hasActivities = true;
12245                    foregroundActivities = true;
12246                    break;
12247                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12248                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12249                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12250                        app.adjType = "pausing";
12251                    }
12252                    app.hidden = false;
12253                    foregroundActivities = true;
12254                } else if (r.state == ActivityState.STOPPING) {
12255                    // We will apply the actual adjustment later, because
12256                    // we want to allow this process to immediately go through
12257                    // any memory trimming that is in effect.
12258                    app.hidden = false;
12259                    foregroundActivities = true;
12260                    hasStoppingActivities = true;
12261                }
12262                if (r.app == app) {
12263                    app.hasActivities = true;
12264                }
12265            }
12266        }
12267
12268        if (adj == hiddenAdj && !app.hasActivities) {
12269            // Whoops, this process is completely empty as far as we know
12270            // at this point.
12271            adj = emptyAdj;
12272            app.empty = true;
12273            app.adjType = "bg-empty";
12274        }
12275
12276        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12277            if (app.foregroundServices) {
12278                // The user is aware of this app, so make it visible.
12279                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12280                app.hidden = false;
12281                app.adjType = "foreground-service";
12282                schedGroup = Process.THREAD_GROUP_DEFAULT;
12283            } else if (app.forcingToForeground != null) {
12284                // The user is aware of this app, so make it visible.
12285                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12286                app.hidden = false;
12287                app.adjType = "force-foreground";
12288                app.adjSource = app.forcingToForeground;
12289                schedGroup = Process.THREAD_GROUP_DEFAULT;
12290            }
12291        }
12292
12293        if (app.foregroundServices) {
12294            interesting = true;
12295        }
12296
12297        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12298            // We don't want to kill the current heavy-weight process.
12299            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12300            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12301            app.hidden = false;
12302            app.adjType = "heavy";
12303        }
12304
12305        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12306            // This process is hosting what we currently consider to be the
12307            // home app, so we don't want to let it go into the background.
12308            adj = ProcessList.HOME_APP_ADJ;
12309            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12310            app.hidden = false;
12311            app.adjType = "home";
12312        }
12313
12314        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12315                && app.activities.size() > 0) {
12316            // This was the previous process that showed UI to the user.
12317            // We want to try to keep it around more aggressively, to give
12318            // a good experience around switching between two apps.
12319            adj = ProcessList.PREVIOUS_APP_ADJ;
12320            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12321            app.hidden = false;
12322            app.adjType = "previous";
12323        }
12324
12325        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12326                + " reason=" + app.adjType);
12327
12328        // By default, we use the computed adjustment.  It may be changed if
12329        // there are applications dependent on our services or providers, but
12330        // this gives us a baseline and makes sure we don't get into an
12331        // infinite recursion.
12332        app.adjSeq = mAdjSeq;
12333        app.curRawAdj = app.nonStoppingAdj = adj;
12334
12335        if (mBackupTarget != null && app == mBackupTarget.app) {
12336            // If possible we want to avoid killing apps while they're being backed up
12337            if (adj > ProcessList.BACKUP_APP_ADJ) {
12338                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12339                adj = ProcessList.BACKUP_APP_ADJ;
12340                app.adjType = "backup";
12341                app.hidden = false;
12342            }
12343        }
12344
12345        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12346                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12347            final long now = SystemClock.uptimeMillis();
12348            // This process is more important if the top activity is
12349            // bound to the service.
12350            Iterator<ServiceRecord> jt = app.services.iterator();
12351            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12352                ServiceRecord s = jt.next();
12353                if (s.startRequested) {
12354                    if (app.hasShownUi && app != mHomeProcess) {
12355                        // If this process has shown some UI, let it immediately
12356                        // go to the LRU list because it may be pretty heavy with
12357                        // UI stuff.  We'll tag it with a label just to help
12358                        // debug and understand what is going on.
12359                        if (adj > ProcessList.SERVICE_ADJ) {
12360                            app.adjType = "started-bg-ui-services";
12361                        }
12362                    } else {
12363                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12364                            // This service has seen some activity within
12365                            // recent memory, so we will keep its process ahead
12366                            // of the background processes.
12367                            if (adj > ProcessList.SERVICE_ADJ) {
12368                                adj = ProcessList.SERVICE_ADJ;
12369                                app.adjType = "started-services";
12370                                app.hidden = false;
12371                            }
12372                        }
12373                        // If we have let the service slide into the background
12374                        // state, still have some text describing what it is doing
12375                        // even though the service no longer has an impact.
12376                        if (adj > ProcessList.SERVICE_ADJ) {
12377                            app.adjType = "started-bg-services";
12378                        }
12379                    }
12380                    // Don't kill this process because it is doing work; it
12381                    // has said it is doing work.
12382                    app.keeping = true;
12383                }
12384                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12385                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12386                    Iterator<ArrayList<ConnectionRecord>> kt
12387                            = s.connections.values().iterator();
12388                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12389                        ArrayList<ConnectionRecord> clist = kt.next();
12390                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12391                            // XXX should compute this based on the max of
12392                            // all connected clients.
12393                            ConnectionRecord cr = clist.get(i);
12394                            if (cr.binding.client == app) {
12395                                // Binding to ourself is not interesting.
12396                                continue;
12397                            }
12398                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12399                                ProcessRecord client = cr.binding.client;
12400                                int clientAdj = adj;
12401                                int myHiddenAdj = hiddenAdj;
12402                                if (myHiddenAdj > client.hiddenAdj) {
12403                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12404                                        myHiddenAdj = client.hiddenAdj;
12405                                    } else {
12406                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12407                                    }
12408                                }
12409                                int myEmptyAdj = emptyAdj;
12410                                if (myEmptyAdj > client.emptyAdj) {
12411                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12412                                        myEmptyAdj = client.emptyAdj;
12413                                    } else {
12414                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12415                                    }
12416                                }
12417                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12418                                        myEmptyAdj, TOP_APP, true, doingAll);
12419                                String adjType = null;
12420                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12421                                    // Not doing bind OOM management, so treat
12422                                    // this guy more like a started service.
12423                                    if (app.hasShownUi && app != mHomeProcess) {
12424                                        // If this process has shown some UI, let it immediately
12425                                        // go to the LRU list because it may be pretty heavy with
12426                                        // UI stuff.  We'll tag it with a label just to help
12427                                        // debug and understand what is going on.
12428                                        if (adj > clientAdj) {
12429                                            adjType = "bound-bg-ui-services";
12430                                        }
12431                                        app.hidden = false;
12432                                        clientAdj = adj;
12433                                    } else {
12434                                        if (now >= (s.lastActivity
12435                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12436                                            // This service has not seen activity within
12437                                            // recent memory, so allow it to drop to the
12438                                            // LRU list if there is no other reason to keep
12439                                            // it around.  We'll also tag it with a label just
12440                                            // to help debug and undertand what is going on.
12441                                            if (adj > clientAdj) {
12442                                                adjType = "bound-bg-services";
12443                                            }
12444                                            clientAdj = adj;
12445                                        }
12446                                    }
12447                                }
12448                                if (adj > clientAdj) {
12449                                    // If this process has recently shown UI, and
12450                                    // the process that is binding to it is less
12451                                    // important than being visible, then we don't
12452                                    // care about the binding as much as we care
12453                                    // about letting this process get into the LRU
12454                                    // list to be killed and restarted if needed for
12455                                    // memory.
12456                                    if (app.hasShownUi && app != mHomeProcess
12457                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12458                                        adjType = "bound-bg-ui-services";
12459                                    } else {
12460                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12461                                                |Context.BIND_IMPORTANT)) != 0) {
12462                                            adj = clientAdj;
12463                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12464                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12465                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12466                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12467                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12468                                            adj = clientAdj;
12469                                        } else {
12470                                            app.pendingUiClean = true;
12471                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12472                                                adj = ProcessList.VISIBLE_APP_ADJ;
12473                                            }
12474                                        }
12475                                        if (!client.hidden) {
12476                                            app.hidden = false;
12477                                        }
12478                                        if (client.keeping) {
12479                                            app.keeping = true;
12480                                        }
12481                                        adjType = "service";
12482                                    }
12483                                }
12484                                if (adjType != null) {
12485                                    app.adjType = adjType;
12486                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12487                                            .REASON_SERVICE_IN_USE;
12488                                    app.adjSource = cr.binding.client;
12489                                    app.adjSourceOom = clientAdj;
12490                                    app.adjTarget = s.name;
12491                                }
12492                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12493                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12494                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12495                                    }
12496                                }
12497                            }
12498                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12499                                ActivityRecord a = cr.activity;
12500                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12501                                        (a.visible || a.state == ActivityState.RESUMED
12502                                         || a.state == ActivityState.PAUSING)) {
12503                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12504                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12505                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12506                                    }
12507                                    app.hidden = false;
12508                                    app.adjType = "service";
12509                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12510                                            .REASON_SERVICE_IN_USE;
12511                                    app.adjSource = a;
12512                                    app.adjSourceOom = adj;
12513                                    app.adjTarget = s.name;
12514                                }
12515                            }
12516                        }
12517                    }
12518                }
12519            }
12520
12521            // Finally, if this process has active services running in it, we
12522            // would like to avoid killing it unless it would prevent the current
12523            // application from running.  By default we put the process in
12524            // with the rest of the background processes; as we scan through
12525            // its services we may bump it up from there.
12526            if (adj > hiddenAdj) {
12527                adj = hiddenAdj;
12528                app.hidden = false;
12529                app.adjType = "bg-services";
12530            }
12531        }
12532
12533        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12534                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12535            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12536            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12537                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12538                ContentProviderRecord cpr = jt.next();
12539                for (int i = cpr.connections.size()-1;
12540                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12541                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12542                        i--) {
12543                    ContentProviderConnection conn = cpr.connections.get(i);
12544                    ProcessRecord client = conn.client;
12545                    if (client == app) {
12546                        // Being our own client is not interesting.
12547                        continue;
12548                    }
12549                    int myHiddenAdj = hiddenAdj;
12550                    if (myHiddenAdj > client.hiddenAdj) {
12551                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12552                            myHiddenAdj = client.hiddenAdj;
12553                        } else {
12554                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12555                        }
12556                    }
12557                    int myEmptyAdj = emptyAdj;
12558                    if (myEmptyAdj > client.emptyAdj) {
12559                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12560                            myEmptyAdj = client.emptyAdj;
12561                        } else {
12562                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12563                        }
12564                    }
12565                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12566                            myEmptyAdj, TOP_APP, true, doingAll);
12567                    if (adj > clientAdj) {
12568                        if (app.hasShownUi && app != mHomeProcess
12569                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12570                            app.adjType = "bg-ui-provider";
12571                        } else {
12572                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12573                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12574                            app.adjType = "provider";
12575                        }
12576                        if (!client.hidden) {
12577                            app.hidden = false;
12578                        }
12579                        if (client.keeping) {
12580                            app.keeping = true;
12581                        }
12582                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12583                                .REASON_PROVIDER_IN_USE;
12584                        app.adjSource = client;
12585                        app.adjSourceOom = clientAdj;
12586                        app.adjTarget = cpr.name;
12587                    }
12588                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12589                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12590                    }
12591                }
12592                // If the provider has external (non-framework) process
12593                // dependencies, ensure that its adjustment is at least
12594                // FOREGROUND_APP_ADJ.
12595                if (cpr.hasExternalProcessHandles()) {
12596                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12597                        adj = ProcessList.FOREGROUND_APP_ADJ;
12598                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12599                        app.hidden = false;
12600                        app.keeping = true;
12601                        app.adjType = "provider";
12602                        app.adjTarget = cpr.name;
12603                    }
12604                }
12605            }
12606        }
12607
12608        if (adj == ProcessList.SERVICE_ADJ) {
12609            if (doingAll) {
12610                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12611                mNewNumServiceProcs++;
12612            }
12613            if (app.serviceb) {
12614                adj = ProcessList.SERVICE_B_ADJ;
12615            }
12616        } else {
12617            app.serviceb = false;
12618        }
12619
12620        app.nonStoppingAdj = adj;
12621
12622        if (hasStoppingActivities) {
12623            // Only upgrade adjustment.
12624            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12625                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12626                app.adjType = "stopping";
12627            }
12628        }
12629
12630        app.curRawAdj = adj;
12631
12632        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12633        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12634        if (adj > app.maxAdj) {
12635            adj = app.maxAdj;
12636            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12637                schedGroup = Process.THREAD_GROUP_DEFAULT;
12638            }
12639        }
12640        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12641            app.keeping = true;
12642        }
12643
12644        if (app.hasAboveClient) {
12645            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12646            // then we need to drop its adjustment to be lower than the service's
12647            // in order to honor the request.  We want to drop it by one adjustment
12648            // level...  but there is special meaning applied to various levels so
12649            // we will skip some of them.
12650            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12651                // System process will not get dropped, ever
12652            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12653                adj = ProcessList.VISIBLE_APP_ADJ;
12654            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12655                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12656            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12657                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
12658            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
12659                adj++;
12660            }
12661        }
12662
12663        int importance = app.memImportance;
12664        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
12665            app.curAdj = adj;
12666            app.curSchedGroup = schedGroup;
12667            if (!interesting) {
12668                // For this reporting, if there is not something explicitly
12669                // interesting in this process then we will push it to the
12670                // background importance.
12671                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12672            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12673                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12674            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
12675                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12676            } else if (adj >= ProcessList.HOME_APP_ADJ) {
12677                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12678            } else if (adj >= ProcessList.SERVICE_ADJ) {
12679                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12680            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12681                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
12682            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
12683                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
12684            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
12685                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
12686            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
12687                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
12688            } else {
12689                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
12690            }
12691        }
12692
12693        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
12694        if (foregroundActivities != app.foregroundActivities) {
12695            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
12696        }
12697        if (changes != 0) {
12698            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
12699            app.memImportance = importance;
12700            app.foregroundActivities = foregroundActivities;
12701            int i = mPendingProcessChanges.size()-1;
12702            ProcessChangeItem item = null;
12703            while (i >= 0) {
12704                item = mPendingProcessChanges.get(i);
12705                if (item.pid == app.pid) {
12706                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
12707                    break;
12708                }
12709                i--;
12710            }
12711            if (i < 0) {
12712                // No existing item in pending changes; need a new one.
12713                final int NA = mAvailProcessChanges.size();
12714                if (NA > 0) {
12715                    item = mAvailProcessChanges.remove(NA-1);
12716                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
12717                } else {
12718                    item = new ProcessChangeItem();
12719                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
12720                }
12721                item.changes = 0;
12722                item.pid = app.pid;
12723                item.uid = app.info.uid;
12724                if (mPendingProcessChanges.size() == 0) {
12725                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
12726                            "*** Enqueueing dispatch processes changed!");
12727                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
12728                }
12729                mPendingProcessChanges.add(item);
12730            }
12731            item.changes |= changes;
12732            item.importance = importance;
12733            item.foregroundActivities = foregroundActivities;
12734            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
12735                    + Integer.toHexString(System.identityHashCode(item))
12736                    + " " + app.toShortString() + ": changes=" + item.changes
12737                    + " importance=" + item.importance
12738                    + " foreground=" + item.foregroundActivities
12739                    + " type=" + app.adjType + " source=" + app.adjSource
12740                    + " target=" + app.adjTarget);
12741        }
12742
12743        return app.curRawAdj;
12744    }
12745
12746    /**
12747     * Ask a given process to GC right now.
12748     */
12749    final void performAppGcLocked(ProcessRecord app) {
12750        try {
12751            app.lastRequestedGc = SystemClock.uptimeMillis();
12752            if (app.thread != null) {
12753                if (app.reportLowMemory) {
12754                    app.reportLowMemory = false;
12755                    app.thread.scheduleLowMemory();
12756                } else {
12757                    app.thread.processInBackground();
12758                }
12759            }
12760        } catch (Exception e) {
12761            // whatever.
12762        }
12763    }
12764
12765    /**
12766     * Returns true if things are idle enough to perform GCs.
12767     */
12768    private final boolean canGcNowLocked() {
12769        boolean processingBroadcasts = false;
12770        for (BroadcastQueue q : mBroadcastQueues) {
12771            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
12772                processingBroadcasts = true;
12773            }
12774        }
12775        return !processingBroadcasts
12776                && (mSleeping || (mMainStack.mResumedActivity != null &&
12777                        mMainStack.mResumedActivity.idle));
12778    }
12779
12780    /**
12781     * Perform GCs on all processes that are waiting for it, but only
12782     * if things are idle.
12783     */
12784    final void performAppGcsLocked() {
12785        final int N = mProcessesToGc.size();
12786        if (N <= 0) {
12787            return;
12788        }
12789        if (canGcNowLocked()) {
12790            while (mProcessesToGc.size() > 0) {
12791                ProcessRecord proc = mProcessesToGc.remove(0);
12792                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
12793                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12794                            <= SystemClock.uptimeMillis()) {
12795                        // To avoid spamming the system, we will GC processes one
12796                        // at a time, waiting a few seconds between each.
12797                        performAppGcLocked(proc);
12798                        scheduleAppGcsLocked();
12799                        return;
12800                    } else {
12801                        // It hasn't been long enough since we last GCed this
12802                        // process...  put it in the list to wait for its time.
12803                        addProcessToGcListLocked(proc);
12804                        break;
12805                    }
12806                }
12807            }
12808
12809            scheduleAppGcsLocked();
12810        }
12811    }
12812
12813    /**
12814     * If all looks good, perform GCs on all processes waiting for them.
12815     */
12816    final void performAppGcsIfAppropriateLocked() {
12817        if (canGcNowLocked()) {
12818            performAppGcsLocked();
12819            return;
12820        }
12821        // Still not idle, wait some more.
12822        scheduleAppGcsLocked();
12823    }
12824
12825    /**
12826     * Schedule the execution of all pending app GCs.
12827     */
12828    final void scheduleAppGcsLocked() {
12829        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
12830
12831        if (mProcessesToGc.size() > 0) {
12832            // Schedule a GC for the time to the next process.
12833            ProcessRecord proc = mProcessesToGc.get(0);
12834            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12835
12836            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
12837            long now = SystemClock.uptimeMillis();
12838            if (when < (now+GC_TIMEOUT)) {
12839                when = now + GC_TIMEOUT;
12840            }
12841            mHandler.sendMessageAtTime(msg, when);
12842        }
12843    }
12844
12845    /**
12846     * Add a process to the array of processes waiting to be GCed.  Keeps the
12847     * list in sorted order by the last GC time.  The process can't already be
12848     * on the list.
12849     */
12850    final void addProcessToGcListLocked(ProcessRecord proc) {
12851        boolean added = false;
12852        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12853            if (mProcessesToGc.get(i).lastRequestedGc <
12854                    proc.lastRequestedGc) {
12855                added = true;
12856                mProcessesToGc.add(i+1, proc);
12857                break;
12858            }
12859        }
12860        if (!added) {
12861            mProcessesToGc.add(0, proc);
12862        }
12863    }
12864
12865    /**
12866     * Set up to ask a process to GC itself.  This will either do it
12867     * immediately, or put it on the list of processes to gc the next
12868     * time things are idle.
12869     */
12870    final void scheduleAppGcLocked(ProcessRecord app) {
12871        long now = SystemClock.uptimeMillis();
12872        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
12873            return;
12874        }
12875        if (!mProcessesToGc.contains(app)) {
12876            addProcessToGcListLocked(app);
12877            scheduleAppGcsLocked();
12878        }
12879    }
12880
12881    final void checkExcessivePowerUsageLocked(boolean doKills) {
12882        updateCpuStatsNow();
12883
12884        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12885        boolean doWakeKills = doKills;
12886        boolean doCpuKills = doKills;
12887        if (mLastPowerCheckRealtime == 0) {
12888            doWakeKills = false;
12889        }
12890        if (mLastPowerCheckUptime == 0) {
12891            doCpuKills = false;
12892        }
12893        if (stats.isScreenOn()) {
12894            doWakeKills = false;
12895        }
12896        final long curRealtime = SystemClock.elapsedRealtime();
12897        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12898        final long curUptime = SystemClock.uptimeMillis();
12899        final long uptimeSince = curUptime - mLastPowerCheckUptime;
12900        mLastPowerCheckRealtime = curRealtime;
12901        mLastPowerCheckUptime = curUptime;
12902        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12903            doWakeKills = false;
12904        }
12905        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12906            doCpuKills = false;
12907        }
12908        int i = mLruProcesses.size();
12909        while (i > 0) {
12910            i--;
12911            ProcessRecord app = mLruProcesses.get(i);
12912            if (!app.keeping) {
12913                long wtime;
12914                synchronized (stats) {
12915                    wtime = stats.getProcessWakeTime(app.info.uid,
12916                            app.pid, curRealtime);
12917                }
12918                long wtimeUsed = wtime - app.lastWakeTime;
12919                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12920                if (DEBUG_POWER) {
12921                    StringBuilder sb = new StringBuilder(128);
12922                    sb.append("Wake for ");
12923                    app.toShortString(sb);
12924                    sb.append(": over ");
12925                    TimeUtils.formatDuration(realtimeSince, sb);
12926                    sb.append(" used ");
12927                    TimeUtils.formatDuration(wtimeUsed, sb);
12928                    sb.append(" (");
12929                    sb.append((wtimeUsed*100)/realtimeSince);
12930                    sb.append("%)");
12931                    Slog.i(TAG, sb.toString());
12932                    sb.setLength(0);
12933                    sb.append("CPU for ");
12934                    app.toShortString(sb);
12935                    sb.append(": over ");
12936                    TimeUtils.formatDuration(uptimeSince, sb);
12937                    sb.append(" used ");
12938                    TimeUtils.formatDuration(cputimeUsed, sb);
12939                    sb.append(" (");
12940                    sb.append((cputimeUsed*100)/uptimeSince);
12941                    sb.append("%)");
12942                    Slog.i(TAG, sb.toString());
12943                }
12944                // If a process has held a wake lock for more
12945                // than 50% of the time during this period,
12946                // that sounds bad.  Kill!
12947                if (doWakeKills && realtimeSince > 0
12948                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
12949                    synchronized (stats) {
12950                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12951                                realtimeSince, wtimeUsed);
12952                    }
12953                    Slog.w(TAG, "Excessive wake lock in " + app.processName
12954                            + " (pid " + app.pid + "): held " + wtimeUsed
12955                            + " during " + realtimeSince);
12956                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12957                            app.processName, app.setAdj, "excessive wake lock");
12958                    Process.killProcessQuiet(app.pid);
12959                } else if (doCpuKills && uptimeSince > 0
12960                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
12961                    synchronized (stats) {
12962                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12963                                uptimeSince, cputimeUsed);
12964                    }
12965                    Slog.w(TAG, "Excessive CPU in " + app.processName
12966                            + " (pid " + app.pid + "): used " + cputimeUsed
12967                            + " during " + uptimeSince);
12968                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12969                            app.processName, app.setAdj, "excessive cpu");
12970                    Process.killProcessQuiet(app.pid);
12971                } else {
12972                    app.lastWakeTime = wtime;
12973                    app.lastCpuTime = app.curCpuTime;
12974                }
12975            }
12976        }
12977    }
12978
12979    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
12980            int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
12981        app.hiddenAdj = hiddenAdj;
12982        app.emptyAdj = emptyAdj;
12983
12984        if (app.thread == null) {
12985            return false;
12986        }
12987
12988        final boolean wasKeeping = app.keeping;
12989
12990        boolean success = true;
12991
12992        computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
12993
12994        if (app.curRawAdj != app.setRawAdj) {
12995            if (wasKeeping && !app.keeping) {
12996                // This app is no longer something we want to keep.  Note
12997                // its current wake lock time to later know to kill it if
12998                // it is not behaving well.
12999                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13000                synchronized (stats) {
13001                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13002                            app.pid, SystemClock.elapsedRealtime());
13003                }
13004                app.lastCpuTime = app.curCpuTime;
13005            }
13006
13007            app.setRawAdj = app.curRawAdj;
13008        }
13009
13010        if (app.curAdj != app.setAdj) {
13011            if (Process.setOomAdj(app.pid, app.curAdj)) {
13012                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13013                    TAG, "Set " + app.pid + " " + app.processName +
13014                    " adj " + app.curAdj + ": " + app.adjType);
13015                app.setAdj = app.curAdj;
13016            } else {
13017                success = false;
13018                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13019            }
13020        }
13021        if (app.setSchedGroup != app.curSchedGroup) {
13022            app.setSchedGroup = app.curSchedGroup;
13023            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13024                    "Setting process group of " + app.processName
13025                    + " to " + app.curSchedGroup);
13026            if (app.waitingToKill != null &&
13027                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13028                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13029                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13030                        app.processName, app.setAdj, app.waitingToKill);
13031                app.killedBackground = true;
13032                Process.killProcessQuiet(app.pid);
13033                success = false;
13034            } else {
13035                if (true) {
13036                    long oldId = Binder.clearCallingIdentity();
13037                    try {
13038                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13039                    } catch (Exception e) {
13040                        Slog.w(TAG, "Failed setting process group of " + app.pid
13041                                + " to " + app.curSchedGroup);
13042                        e.printStackTrace();
13043                    } finally {
13044                        Binder.restoreCallingIdentity(oldId);
13045                    }
13046                } else {
13047                    if (app.thread != null) {
13048                        try {
13049                            app.thread.setSchedulingGroup(app.curSchedGroup);
13050                        } catch (RemoteException e) {
13051                        }
13052                    }
13053                }
13054            }
13055        }
13056        return success;
13057    }
13058
13059    private final ActivityRecord resumedAppLocked() {
13060        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13061        if (resumedActivity == null || resumedActivity.app == null) {
13062            resumedActivity = mMainStack.mPausingActivity;
13063            if (resumedActivity == null || resumedActivity.app == null) {
13064                resumedActivity = mMainStack.topRunningActivityLocked(null);
13065            }
13066        }
13067        return resumedActivity;
13068    }
13069
13070    final boolean updateOomAdjLocked(ProcessRecord app) {
13071        final ActivityRecord TOP_ACT = resumedAppLocked();
13072        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13073        int curAdj = app.curAdj;
13074        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13075            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13076
13077        mAdjSeq++;
13078
13079        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
13080                TOP_APP, false);
13081        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13082            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13083        if (nowHidden != wasHidden) {
13084            // Changed to/from hidden state, so apps after it in the LRU
13085            // list may also be changed.
13086            updateOomAdjLocked();
13087        }
13088        return success;
13089    }
13090
13091    final void updateOomAdjLocked() {
13092        final ActivityRecord TOP_ACT = resumedAppLocked();
13093        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13094
13095        if (false) {
13096            RuntimeException e = new RuntimeException();
13097            e.fillInStackTrace();
13098            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13099        }
13100
13101        mAdjSeq++;
13102        mNewNumServiceProcs = 0;
13103
13104        // Let's determine how many processes we have running vs.
13105        // how many slots we have for background processes; we may want
13106        // to put multiple processes in a slot of there are enough of
13107        // them.
13108        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13109                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13110        int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
13111        if (emptyFactor < 1) emptyFactor = 1;
13112        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13113        if (hiddenFactor < 1) hiddenFactor = 1;
13114        int stepHidden = 0;
13115        int stepEmpty = 0;
13116        final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13117        final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13118        int numHidden = 0;
13119        int numEmpty = 0;
13120        int numTrimming = 0;
13121
13122        mNumNonHiddenProcs = 0;
13123        mNumHiddenProcs = 0;
13124
13125        // First update the OOM adjustment for each of the
13126        // application processes based on their current state.
13127        int i = mLruProcesses.size();
13128        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13129        int nextHiddenAdj = curHiddenAdj+1;
13130        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13131        int nextEmptyAdj = curEmptyAdj+2;
13132        while (i > 0) {
13133            i--;
13134            ProcessRecord app = mLruProcesses.get(i);
13135            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13136            updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
13137            if (!app.killedBackground) {
13138                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13139                    // This process was assigned as a hidden process...  step the
13140                    // hidden level.
13141                    mNumHiddenProcs++;
13142                    if (curHiddenAdj != nextHiddenAdj) {
13143                        stepHidden++;
13144                        if (stepHidden >= hiddenFactor) {
13145                            stepHidden = 0;
13146                            curHiddenAdj = nextHiddenAdj;
13147                            nextHiddenAdj += 2;
13148                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13149                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13150                            }
13151                        }
13152                    }
13153                    numHidden++;
13154                    if (numHidden > hiddenProcessLimit) {
13155                        Slog.i(TAG, "No longer want " + app.processName
13156                                + " (pid " + app.pid + "): hidden #" + numHidden);
13157                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13158                                app.processName, app.setAdj, "too many background");
13159                        app.killedBackground = true;
13160                        Process.killProcessQuiet(app.pid);
13161                    }
13162                } else {
13163                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13164                        // This process was assigned as an empty process...  step the
13165                        // empty level.
13166                        if (curEmptyAdj != nextEmptyAdj) {
13167                            stepEmpty++;
13168                            if (stepEmpty >= emptyFactor) {
13169                                stepEmpty = 0;
13170                                curEmptyAdj = nextEmptyAdj;
13171                                nextEmptyAdj += 2;
13172                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13173                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13174                                }
13175                            }
13176                        }
13177                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13178                        mNumNonHiddenProcs++;
13179                    }
13180                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13181                        numEmpty++;
13182                        if (numEmpty > emptyProcessLimit) {
13183                            Slog.i(TAG, "No longer want " + app.processName
13184                                    + " (pid " + app.pid + "): empty #" + numEmpty);
13185                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13186                                    app.processName, app.setAdj, "too many background");
13187                            app.killedBackground = true;
13188                            Process.killProcessQuiet(app.pid);
13189                        }
13190                    }
13191                }
13192                if (app.isolated && app.services.size() <= 0) {
13193                    // If this is an isolated process, and there are no
13194                    // services running in it, then the process is no longer
13195                    // needed.  We agressively kill these because we can by
13196                    // definition not re-use the same process again, and it is
13197                    // good to avoid having whatever code was running in them
13198                    // left sitting around after no longer needed.
13199                    Slog.i(TAG, "Isolated process " + app.processName
13200                            + " (pid " + app.pid + ") no longer needed");
13201                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13202                            app.processName, app.setAdj, "isolated not needed");
13203                    app.killedBackground = true;
13204                    Process.killProcessQuiet(app.pid);
13205                }
13206                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13207                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13208                        && !app.killedBackground) {
13209                    numTrimming++;
13210                }
13211            }
13212        }
13213
13214        mNumServiceProcs = mNewNumServiceProcs;
13215
13216        // Now determine the memory trimming level of background processes.
13217        // Unfortunately we need to start at the back of the list to do this
13218        // properly.  We only do this if the number of background apps we
13219        // are managing to keep around is less than half the maximum we desire;
13220        // if we are keeping a good number around, we'll let them use whatever
13221        // memory they want.
13222        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13223                && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13224            final int numHiddenAndEmpty = numHidden + numEmpty;
13225            final int N = mLruProcesses.size();
13226            int factor = numTrimming/3;
13227            int minFactor = 2;
13228            if (mHomeProcess != null) minFactor++;
13229            if (mPreviousProcess != null) minFactor++;
13230            if (factor < minFactor) factor = minFactor;
13231            int step = 0;
13232            int fgTrimLevel;
13233            if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13234                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13235            } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13236                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13237            } else {
13238                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13239            }
13240            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13241            for (i=0; i<N; i++) {
13242                ProcessRecord app = mLruProcesses.get(i);
13243                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13244                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13245                        && !app.killedBackground) {
13246                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13247                        try {
13248                            app.thread.scheduleTrimMemory(curLevel);
13249                        } catch (RemoteException e) {
13250                        }
13251                        if (false) {
13252                            // For now we won't do this; our memory trimming seems
13253                            // to be good enough at this point that destroying
13254                            // activities causes more harm than good.
13255                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13256                                    && app != mHomeProcess && app != mPreviousProcess) {
13257                                // Need to do this on its own message because the stack may not
13258                                // be in a consistent state at this point.
13259                                // For these apps we will also finish their activities
13260                                // to help them free memory.
13261                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13262                            }
13263                        }
13264                    }
13265                    app.trimMemoryLevel = curLevel;
13266                    step++;
13267                    if (step >= factor) {
13268                        step = 0;
13269                        switch (curLevel) {
13270                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13271                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13272                                break;
13273                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13274                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13275                                break;
13276                        }
13277                    }
13278                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13279                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13280                            && app.thread != null) {
13281                        try {
13282                            app.thread.scheduleTrimMemory(
13283                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13284                        } catch (RemoteException e) {
13285                        }
13286                    }
13287                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13288                } else {
13289                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13290                            && app.pendingUiClean) {
13291                        // If this application is now in the background and it
13292                        // had done UI, then give it the special trim level to
13293                        // have it free UI resources.
13294                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13295                        if (app.trimMemoryLevel < level && app.thread != null) {
13296                            try {
13297                                app.thread.scheduleTrimMemory(level);
13298                            } catch (RemoteException e) {
13299                            }
13300                        }
13301                        app.pendingUiClean = false;
13302                    }
13303                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13304                        try {
13305                            app.thread.scheduleTrimMemory(fgTrimLevel);
13306                        } catch (RemoteException e) {
13307                        }
13308                    }
13309                    app.trimMemoryLevel = fgTrimLevel;
13310                }
13311            }
13312        } else {
13313            final int N = mLruProcesses.size();
13314            for (i=0; i<N; i++) {
13315                ProcessRecord app = mLruProcesses.get(i);
13316                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13317                        && app.pendingUiClean) {
13318                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13319                            && app.thread != null) {
13320                        try {
13321                            app.thread.scheduleTrimMemory(
13322                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13323                        } catch (RemoteException e) {
13324                        }
13325                    }
13326                    app.pendingUiClean = false;
13327                }
13328                app.trimMemoryLevel = 0;
13329            }
13330        }
13331
13332        if (mAlwaysFinishActivities) {
13333            // Need to do this on its own message because the stack may not
13334            // be in a consistent state at this point.
13335            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13336        }
13337    }
13338
13339    final void trimApplications() {
13340        synchronized (this) {
13341            int i;
13342
13343            // First remove any unused application processes whose package
13344            // has been removed.
13345            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13346                final ProcessRecord app = mRemovedProcesses.get(i);
13347                if (app.activities.size() == 0
13348                        && app.curReceiver == null && app.services.size() == 0) {
13349                    Slog.i(
13350                        TAG, "Exiting empty application process "
13351                        + app.processName + " ("
13352                        + (app.thread != null ? app.thread.asBinder() : null)
13353                        + ")\n");
13354                    if (app.pid > 0 && app.pid != MY_PID) {
13355                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13356                                app.processName, app.setAdj, "empty");
13357                        Process.killProcessQuiet(app.pid);
13358                    } else {
13359                        try {
13360                            app.thread.scheduleExit();
13361                        } catch (Exception e) {
13362                            // Ignore exceptions.
13363                        }
13364                    }
13365                    cleanUpApplicationRecordLocked(app, false, true, -1);
13366                    mRemovedProcesses.remove(i);
13367
13368                    if (app.persistent) {
13369                        if (app.persistent) {
13370                            addAppLocked(app.info, false);
13371                        }
13372                    }
13373                }
13374            }
13375
13376            // Now update the oom adj for all processes.
13377            updateOomAdjLocked();
13378        }
13379    }
13380
13381    /** This method sends the specified signal to each of the persistent apps */
13382    public void signalPersistentProcesses(int sig) throws RemoteException {
13383        if (sig != Process.SIGNAL_USR1) {
13384            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13385        }
13386
13387        synchronized (this) {
13388            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13389                    != PackageManager.PERMISSION_GRANTED) {
13390                throw new SecurityException("Requires permission "
13391                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13392            }
13393
13394            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13395                ProcessRecord r = mLruProcesses.get(i);
13396                if (r.thread != null && r.persistent) {
13397                    Process.sendSignal(r.pid, sig);
13398                }
13399            }
13400        }
13401    }
13402
13403    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13404        if (proc == null || proc == mProfileProc) {
13405            proc = mProfileProc;
13406            path = mProfileFile;
13407            profileType = mProfileType;
13408            clearProfilerLocked();
13409        }
13410        if (proc == null) {
13411            return;
13412        }
13413        try {
13414            proc.thread.profilerControl(false, path, null, profileType);
13415        } catch (RemoteException e) {
13416            throw new IllegalStateException("Process disappeared");
13417        }
13418    }
13419
13420    private void clearProfilerLocked() {
13421        if (mProfileFd != null) {
13422            try {
13423                mProfileFd.close();
13424            } catch (IOException e) {
13425            }
13426        }
13427        mProfileApp = null;
13428        mProfileProc = null;
13429        mProfileFile = null;
13430        mProfileType = 0;
13431        mAutoStopProfiler = false;
13432    }
13433
13434    public boolean profileControl(String process, boolean start,
13435            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13436
13437        try {
13438            synchronized (this) {
13439                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13440                // its own permission.
13441                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13442                        != PackageManager.PERMISSION_GRANTED) {
13443                    throw new SecurityException("Requires permission "
13444                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13445                }
13446
13447                if (start && fd == null) {
13448                    throw new IllegalArgumentException("null fd");
13449                }
13450
13451                ProcessRecord proc = null;
13452                if (process != null) {
13453                    try {
13454                        int pid = Integer.parseInt(process);
13455                        synchronized (mPidsSelfLocked) {
13456                            proc = mPidsSelfLocked.get(pid);
13457                        }
13458                    } catch (NumberFormatException e) {
13459                    }
13460
13461                    if (proc == null) {
13462                        HashMap<String, SparseArray<ProcessRecord>> all
13463                                = mProcessNames.getMap();
13464                        SparseArray<ProcessRecord> procs = all.get(process);
13465                        if (procs != null && procs.size() > 0) {
13466                            proc = procs.valueAt(0);
13467                        }
13468                    }
13469                }
13470
13471                if (start && (proc == null || proc.thread == null)) {
13472                    throw new IllegalArgumentException("Unknown process: " + process);
13473                }
13474
13475                if (start) {
13476                    stopProfilerLocked(null, null, 0);
13477                    setProfileApp(proc.info, proc.processName, path, fd, false);
13478                    mProfileProc = proc;
13479                    mProfileType = profileType;
13480                    try {
13481                        fd = fd.dup();
13482                    } catch (IOException e) {
13483                        fd = null;
13484                    }
13485                    proc.thread.profilerControl(start, path, fd, profileType);
13486                    fd = null;
13487                    mProfileFd = null;
13488                } else {
13489                    stopProfilerLocked(proc, path, profileType);
13490                    if (fd != null) {
13491                        try {
13492                            fd.close();
13493                        } catch (IOException e) {
13494                        }
13495                    }
13496                }
13497
13498                return true;
13499            }
13500        } catch (RemoteException e) {
13501            throw new IllegalStateException("Process disappeared");
13502        } finally {
13503            if (fd != null) {
13504                try {
13505                    fd.close();
13506                } catch (IOException e) {
13507                }
13508            }
13509        }
13510    }
13511
13512    public boolean dumpHeap(String process, boolean managed,
13513            String path, ParcelFileDescriptor fd) throws RemoteException {
13514
13515        try {
13516            synchronized (this) {
13517                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13518                // its own permission (same as profileControl).
13519                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13520                        != PackageManager.PERMISSION_GRANTED) {
13521                    throw new SecurityException("Requires permission "
13522                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13523                }
13524
13525                if (fd == null) {
13526                    throw new IllegalArgumentException("null fd");
13527                }
13528
13529                ProcessRecord proc = null;
13530                try {
13531                    int pid = Integer.parseInt(process);
13532                    synchronized (mPidsSelfLocked) {
13533                        proc = mPidsSelfLocked.get(pid);
13534                    }
13535                } catch (NumberFormatException e) {
13536                }
13537
13538                if (proc == null) {
13539                    HashMap<String, SparseArray<ProcessRecord>> all
13540                            = mProcessNames.getMap();
13541                    SparseArray<ProcessRecord> procs = all.get(process);
13542                    if (procs != null && procs.size() > 0) {
13543                        proc = procs.valueAt(0);
13544                    }
13545                }
13546
13547                if (proc == null || proc.thread == null) {
13548                    throw new IllegalArgumentException("Unknown process: " + process);
13549                }
13550
13551                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13552                if (!isDebuggable) {
13553                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13554                        throw new SecurityException("Process not debuggable: " + proc);
13555                    }
13556                }
13557
13558                proc.thread.dumpHeap(managed, path, fd);
13559                fd = null;
13560                return true;
13561            }
13562        } catch (RemoteException e) {
13563            throw new IllegalStateException("Process disappeared");
13564        } finally {
13565            if (fd != null) {
13566                try {
13567                    fd.close();
13568                } catch (IOException e) {
13569                }
13570            }
13571        }
13572    }
13573
13574    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13575    public void monitor() {
13576        synchronized (this) { }
13577    }
13578
13579    void onCoreSettingsChange(Bundle settings) {
13580        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13581            ProcessRecord processRecord = mLruProcesses.get(i);
13582            try {
13583                if (processRecord.thread != null) {
13584                    processRecord.thread.setCoreSettings(settings);
13585                }
13586            } catch (RemoteException re) {
13587                /* ignore */
13588            }
13589        }
13590    }
13591
13592    // Multi-user methods
13593
13594    @Override
13595    public boolean switchUser(int userId) {
13596        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13597                != PackageManager.PERMISSION_GRANTED) {
13598            String msg = "Permission Denial: switchUser() from pid="
13599                    + Binder.getCallingPid()
13600                    + ", uid=" + Binder.getCallingUid()
13601                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13602            Slog.w(TAG, msg);
13603            throw new SecurityException(msg);
13604        }
13605        synchronized (this) {
13606            if (mCurrentUserId == userId) {
13607                return true;
13608            }
13609
13610            // If the user we are switching to is not currently started, then
13611            // we need to start it now.
13612            if (mStartedUsers.get(userId) == null) {
13613                mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
13614            }
13615
13616            mCurrentUserId = userId;
13617            boolean haveActivities = mMainStack.switchUser(userId);
13618            if (!haveActivities) {
13619                startHomeActivityLocked(userId, mStartedUsers.get(userId));
13620            }
13621        }
13622
13623        long ident = Binder.clearCallingIdentity();
13624        try {
13625            // Inform of user switch
13626            Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
13627            addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13628            mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_USERS);
13629        } finally {
13630            Binder.restoreCallingIdentity(ident);
13631        }
13632
13633        return true;
13634    }
13635
13636    void finishUserSwitch(UserStartedState uss) {
13637        synchronized (this) {
13638            if (uss.mState == UserStartedState.STATE_BOOTING
13639                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
13640                uss.mState = UserStartedState.STATE_RUNNING;
13641                broadcastIntentLocked(null, null,
13642                        new Intent(Intent.ACTION_BOOT_COMPLETED, null),
13643                        null, null, 0, null, null,
13644                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
13645                        false, false, MY_PID, Process.SYSTEM_UID, uss.mHandle.getIdentifier());
13646            }
13647        }
13648    }
13649
13650    @Override
13651    public int stopUser(final int userId, final IStopUserCallback callback) {
13652        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13653                != PackageManager.PERMISSION_GRANTED) {
13654            String msg = "Permission Denial: switchUser() from pid="
13655                    + Binder.getCallingPid()
13656                    + ", uid=" + Binder.getCallingUid()
13657                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13658            Slog.w(TAG, msg);
13659            throw new SecurityException(msg);
13660        }
13661        if (userId <= 0) {
13662            throw new IllegalArgumentException("Can't stop primary user " + userId);
13663        }
13664        synchronized (this) {
13665            if (mCurrentUserId == userId) {
13666                return ActivityManager.USER_OP_IS_CURRENT;
13667            }
13668
13669            final UserStartedState uss = mStartedUsers.get(userId);
13670            if (uss == null) {
13671                // User is not started, nothing to do...  but we do need to
13672                // callback if requested.
13673                if (callback != null) {
13674                    mHandler.post(new Runnable() {
13675                        @Override
13676                        public void run() {
13677                            try {
13678                                callback.userStopped(userId);
13679                            } catch (RemoteException e) {
13680                            }
13681                        }
13682                    });
13683                }
13684                return ActivityManager.USER_OP_SUCCESS;
13685            }
13686
13687            if (callback != null) {
13688                uss.mStopCallbacks.add(callback);
13689            }
13690
13691            if (uss.mState != UserStartedState.STATE_STOPPING) {
13692                uss.mState = UserStartedState.STATE_STOPPING;
13693
13694                long ident = Binder.clearCallingIdentity();
13695                try {
13696                    // Inform of user switch
13697                    Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13698                    final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() {
13699                        @Override
13700                        public void performReceive(Intent intent, int resultCode, String data,
13701                                Bundle extras, boolean ordered, boolean sticky) {
13702                            finishUserStop(uss);
13703                        }
13704                    };
13705                    broadcastIntentLocked(null, null, intent,
13706                            null, resultReceiver, 0, null, null, null,
13707                            true, false, MY_PID, Process.SYSTEM_UID, userId);
13708                } finally {
13709                    Binder.restoreCallingIdentity(ident);
13710                }
13711            }
13712        }
13713
13714        return ActivityManager.USER_OP_SUCCESS;
13715    }
13716
13717    void finishUserStop(UserStartedState uss) {
13718        final int userId = uss.mHandle.getIdentifier();
13719        boolean stopped;
13720        ArrayList<IStopUserCallback> callbacks;
13721        synchronized (this) {
13722            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
13723            if (uss.mState != UserStartedState.STATE_STOPPING
13724                    || mStartedUsers.get(userId) != uss) {
13725                stopped = false;
13726            } else {
13727                stopped = true;
13728                // User can no longer run.
13729                mStartedUsers.remove(userId);
13730
13731                // Clean up all state and processes associated with the user.
13732                // Kill all the processes for the user.
13733                forceStopUserLocked(userId);
13734            }
13735        }
13736
13737        for (int i=0; i<callbacks.size(); i++) {
13738            try {
13739                if (stopped) callbacks.get(i).userStopped(userId);
13740                else callbacks.get(i).userStopAborted(userId);
13741            } catch (RemoteException e) {
13742            }
13743        }
13744    }
13745
13746    @Override
13747    public UserInfo getCurrentUser() {
13748        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13749                != PackageManager.PERMISSION_GRANTED) {
13750            String msg = "Permission Denial: getCurrentUser() from pid="
13751                    + Binder.getCallingPid()
13752                    + ", uid=" + Binder.getCallingUid()
13753                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13754            Slog.w(TAG, msg);
13755            throw new SecurityException(msg);
13756        }
13757        synchronized (this) {
13758            return getUserManager().getUserInfo(mCurrentUserId);
13759        }
13760    }
13761
13762    private boolean userExists(int userId) {
13763        UserInfo user = getUserManager().getUserInfo(userId);
13764        return user != null;
13765    }
13766
13767    UserManager getUserManager() {
13768        if (mUserManager == null) {
13769            mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
13770        }
13771        return mUserManager;
13772    }
13773
13774    private void checkValidCaller(int uid, int userId) {
13775        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
13776
13777        throw new SecurityException("Caller uid=" + uid
13778                + " is not privileged to communicate with user=" + userId);
13779    }
13780
13781    private int applyUserId(int uid, int userId) {
13782        return UserHandle.getUid(userId, uid);
13783    }
13784
13785    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
13786        if (info == null) return null;
13787        ApplicationInfo newInfo = new ApplicationInfo(info);
13788        newInfo.uid = applyUserId(info.uid, userId);
13789        newInfo.dataDir = USER_DATA_DIR + userId + "/"
13790                + info.packageName;
13791        return newInfo;
13792    }
13793
13794    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
13795        if (aInfo == null
13796                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
13797            return aInfo;
13798        }
13799
13800        ActivityInfo info = new ActivityInfo(aInfo);
13801        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
13802        return info;
13803    }
13804}
13805