ActivityManagerService.java revision 2d1b37819112274f538d1886c379ff337eb0d9ed
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.TimeUtils;
125import android.view.Gravity;
126import android.view.LayoutInflater;
127import android.view.View;
128import android.view.WindowManager;
129import android.view.WindowManagerPolicy;
130
131import java.io.BufferedInputStream;
132import java.io.BufferedOutputStream;
133import java.io.BufferedReader;
134import java.io.DataInputStream;
135import java.io.DataOutputStream;
136import java.io.File;
137import java.io.FileDescriptor;
138import java.io.FileInputStream;
139import java.io.FileNotFoundException;
140import java.io.FileOutputStream;
141import java.io.IOException;
142import java.io.InputStreamReader;
143import java.io.PrintWriter;
144import java.io.StringWriter;
145import java.lang.ref.WeakReference;
146import java.util.ArrayList;
147import java.util.Collections;
148import java.util.Comparator;
149import java.util.HashMap;
150import java.util.HashSet;
151import java.util.Iterator;
152import java.util.List;
153import java.util.Locale;
154import java.util.Map;
155import java.util.Set;
156import java.util.concurrent.atomic.AtomicBoolean;
157import java.util.concurrent.atomic.AtomicLong;
158
159public final class ActivityManagerService extends ActivityManagerNative
160        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
161    private static final String USER_DATA_DIR = "/data/user/";
162    static final String TAG = "ActivityManager";
163    static final String TAG_MU = "ActivityManagerServiceMU";
164    static final boolean DEBUG = false;
165    static final boolean localLOGV = DEBUG;
166    static final boolean DEBUG_SWITCH = localLOGV || false;
167    static final boolean DEBUG_TASKS = localLOGV || false;
168    static final boolean DEBUG_PAUSE = localLOGV || false;
169    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
170    static final boolean DEBUG_TRANSITION = localLOGV || false;
171    static final boolean DEBUG_BROADCAST = localLOGV || false;
172    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
173    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
174    static final boolean DEBUG_SERVICE = localLOGV || false;
175    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
176    static final boolean DEBUG_VISBILITY = localLOGV || false;
177    static final boolean DEBUG_PROCESSES = localLOGV || false;
178    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
179    static final boolean DEBUG_PROVIDER = localLOGV || false;
180    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
181    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
182    static final boolean DEBUG_RESULTS = localLOGV || false;
183    static final boolean DEBUG_BACKUP = localLOGV || false;
184    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
185    static final boolean DEBUG_POWER = localLOGV || false;
186    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
187    static final boolean DEBUG_MU = localLOGV || false;
188    static final boolean VALIDATE_TOKENS = false;
189    static final boolean SHOW_ACTIVITY_START_TIME = true;
190
191    // Control over CPU and battery monitoring.
192    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
193    static final boolean MONITOR_CPU_USAGE = true;
194    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
195    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
196    static final boolean MONITOR_THREAD_CPU_USAGE = false;
197
198    // The flags that are set for all calls we make to the package manager.
199    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
200
201    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
202
203    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
204
205    // Maximum number of recent tasks that we can remember.
206    static final int MAX_RECENT_TASKS = 20;
207
208    // Amount of time after a call to stopAppSwitches() during which we will
209    // prevent further untrusted switches from happening.
210    static final long APP_SWITCH_DELAY_TIME = 5*1000;
211
212    // How long we wait for a launched process to attach to the activity manager
213    // before we decide it's never going to come up for real.
214    static final int PROC_START_TIMEOUT = 10*1000;
215
216    // How long we wait for a launched process to attach to the activity manager
217    // before we decide it's never going to come up for real, when the process was
218    // started with a wrapper for instrumentation (such as Valgrind) because it
219    // could take much longer than usual.
220    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
221
222    // How long to wait after going idle before forcing apps to GC.
223    static final int GC_TIMEOUT = 5*1000;
224
225    // The minimum amount of time between successive GC requests for a process.
226    static final int GC_MIN_INTERVAL = 60*1000;
227
228    // The rate at which we check for apps using excessive power -- 15 mins.
229    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
230
231    // The minimum sample duration we will allow before deciding we have
232    // enough data on wake locks to start killing things.
233    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
234
235    // The minimum sample duration we will allow before deciding we have
236    // enough data on CPU usage to start killing things.
237    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
238
239    // How long we allow a receiver to run before giving up on it.
240    static final int BROADCAST_FG_TIMEOUT = 10*1000;
241    static final int BROADCAST_BG_TIMEOUT = 60*1000;
242
243    // How long we wait until we timeout on key dispatching.
244    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
245
246    // How long we wait until we timeout on key dispatching during instrumentation.
247    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
248
249    static final int MY_PID = Process.myPid();
250
251    static final String[] EMPTY_STRING_ARRAY = new String[0];
252
253    public ActivityStack mMainStack;
254
255    private final boolean mHeadless;
256
257    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
258    // default actuion automatically.  Important for devices without direct input
259    // devices.
260    private boolean mShowDialogs = true;
261
262    /**
263     * Description of a request to start a new activity, which has been held
264     * due to app switches being disabled.
265     */
266    static class PendingActivityLaunch {
267        ActivityRecord r;
268        ActivityRecord sourceRecord;
269        int startFlags;
270    }
271
272    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
273            = new ArrayList<PendingActivityLaunch>();
274
275
276    BroadcastQueue mFgBroadcastQueue;
277    BroadcastQueue mBgBroadcastQueue;
278    // Convenient for easy iteration over the queues. Foreground is first
279    // so that dispatch of foreground broadcasts gets precedence.
280    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
281
282    BroadcastQueue broadcastQueueForIntent(Intent intent) {
283        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
284        if (DEBUG_BACKGROUND_BROADCAST) {
285            Slog.i(TAG, "Broadcast intent " + intent + " on "
286                    + (isFg ? "foreground" : "background")
287                    + " queue");
288        }
289        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
290    }
291
292    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
293        for (BroadcastQueue queue : mBroadcastQueues) {
294            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
295            if (r != null) {
296                return r;
297            }
298        }
299        return null;
300    }
301
302    /**
303     * Activity we have told the window manager to have key focus.
304     */
305    ActivityRecord mFocusedActivity = null;
306    /**
307     * List of intents that were used to start the most recent tasks.
308     */
309    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
310
311    /**
312     * Process management.
313     */
314    final ProcessList mProcessList = new ProcessList();
315
316    /**
317     * All of the applications we currently have running organized by name.
318     * The keys are strings of the application package name (as
319     * returned by the package manager), and the keys are ApplicationRecord
320     * objects.
321     */
322    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
323
324    /**
325     * The currently running isolated processes.
326     */
327    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
328
329    /**
330     * Counter for assigning isolated process uids, to avoid frequently reusing the
331     * same ones.
332     */
333    int mNextIsolatedProcessUid = 0;
334
335    /**
336     * The currently running heavy-weight process, if any.
337     */
338    ProcessRecord mHeavyWeightProcess = null;
339
340    /**
341     * The last time that various processes have crashed.
342     */
343    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
344
345    /**
346     * Set of applications that we consider to be bad, and will reject
347     * incoming broadcasts from (which the user has no control over).
348     * Processes are added to this set when they have crashed twice within
349     * a minimum amount of time; they are removed from it when they are
350     * later restarted (hopefully due to some user action).  The value is the
351     * time it was added to the list.
352     */
353    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
354
355    /**
356     * All of the processes we currently have running organized by pid.
357     * The keys are the pid running the application.
358     *
359     * <p>NOTE: This object is protected by its own lock, NOT the global
360     * activity manager lock!
361     */
362    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
363
364    /**
365     * All of the processes that have been forced to be foreground.  The key
366     * is the pid of the caller who requested it (we hold a death
367     * link on it).
368     */
369    abstract class ForegroundToken implements IBinder.DeathRecipient {
370        int pid;
371        IBinder token;
372    }
373    final SparseArray<ForegroundToken> mForegroundProcesses
374            = new SparseArray<ForegroundToken>();
375
376    /**
377     * List of records for processes that someone had tried to start before the
378     * system was ready.  We don't start them at that point, but ensure they
379     * are started by the time booting is complete.
380     */
381    final ArrayList<ProcessRecord> mProcessesOnHold
382            = new ArrayList<ProcessRecord>();
383
384    /**
385     * List of persistent applications that are in the process
386     * of being started.
387     */
388    final ArrayList<ProcessRecord> mPersistentStartingProcesses
389            = new ArrayList<ProcessRecord>();
390
391    /**
392     * Processes that are being forcibly torn down.
393     */
394    final ArrayList<ProcessRecord> mRemovedProcesses
395            = new ArrayList<ProcessRecord>();
396
397    /**
398     * List of running applications, sorted by recent usage.
399     * The first entry in the list is the least recently used.
400     * It contains ApplicationRecord objects.  This list does NOT include
401     * any persistent application records (since we never want to exit them).
402     */
403    final ArrayList<ProcessRecord> mLruProcesses
404            = new ArrayList<ProcessRecord>();
405
406    /**
407     * List of processes that should gc as soon as things are idle.
408     */
409    final ArrayList<ProcessRecord> mProcessesToGc
410            = new ArrayList<ProcessRecord>();
411
412    /**
413     * This is the process holding what we currently consider to be
414     * the "home" activity.
415     */
416    ProcessRecord mHomeProcess;
417
418    /**
419     * This is the process holding the activity the user last visited that
420     * is in a different process from the one they are currently in.
421     */
422    ProcessRecord mPreviousProcess;
423
424    /**
425     * The time at which the previous process was last visible.
426     */
427    long mPreviousProcessVisibleTime;
428
429    /**
430     * Which uses have been started, so are allowed to run code.
431     */
432    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
433
434    /**
435     * LRU list of history of current users.  Most recently current is at the end.
436     */
437    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
438
439    /**
440     * Packages that the user has asked to have run in screen size
441     * compatibility mode instead of filling the screen.
442     */
443    final CompatModePackages mCompatModePackages;
444
445    /**
446     * Set of PendingResultRecord objects that are currently active.
447     */
448    final HashSet mPendingResultRecords = new HashSet();
449
450    /**
451     * Set of IntentSenderRecord objects that are currently active.
452     */
453    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
454            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
455
456    /**
457     * Fingerprints (hashCode()) of stack traces that we've
458     * already logged DropBox entries for.  Guarded by itself.  If
459     * something (rogue user app) forces this over
460     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
461     */
462    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
463    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
464
465    /**
466     * Strict Mode background batched logging state.
467     *
468     * The string buffer is guarded by itself, and its lock is also
469     * used to determine if another batched write is already
470     * in-flight.
471     */
472    private final StringBuilder mStrictModeBuffer = new StringBuilder();
473
474    /**
475     * Keeps track of all IIntentReceivers that have been registered for
476     * broadcasts.  Hash keys are the receiver IBinder, hash value is
477     * a ReceiverList.
478     */
479    final HashMap mRegisteredReceivers = new HashMap();
480
481    /**
482     * Resolver for broadcast intents to registered receivers.
483     * Holds BroadcastFilter (subclass of IntentFilter).
484     */
485    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
486            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
487        @Override
488        protected boolean allowFilterResult(
489                BroadcastFilter filter, List<BroadcastFilter> dest) {
490            IBinder target = filter.receiverList.receiver.asBinder();
491            for (int i=dest.size()-1; i>=0; i--) {
492                if (dest.get(i).receiverList.receiver.asBinder() == target) {
493                    return false;
494                }
495            }
496            return true;
497        }
498
499        @Override
500        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
501            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
502                    || userId == filter.owningUserId) {
503                return super.newResult(filter, match, userId);
504            }
505            return null;
506        }
507
508        @Override
509        protected BroadcastFilter[] newArray(int size) {
510            return new BroadcastFilter[size];
511        }
512
513        @Override
514        protected String packageForFilter(BroadcastFilter filter) {
515            return filter.packageName;
516        }
517    };
518
519    /**
520     * State of all active sticky broadcasts per user.  Keys are the action of the
521     * sticky Intent, values are an ArrayList of all broadcasted intents with
522     * that action (which should usually be one).  The SparseArray is keyed
523     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
524     * for stickies that are sent to all users.
525     */
526    final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
527            new SparseArray<HashMap<String, ArrayList<Intent>>>();
528
529    final ActiveServices mServices;
530
531    /**
532     * Backup/restore process management
533     */
534    String mBackupAppName = null;
535    BackupRecord mBackupTarget = null;
536
537    /**
538     * List of PendingThumbnailsRecord objects of clients who are still
539     * waiting to receive all of the thumbnails for a task.
540     */
541    final ArrayList mPendingThumbnails = new ArrayList();
542
543    /**
544     * List of HistoryRecord objects that have been finished and must
545     * still report back to a pending thumbnail receiver.
546     */
547    final ArrayList mCancelledThumbnails = new ArrayList();
548
549    final ProviderMap mProviderMap;
550
551    /**
552     * List of content providers who have clients waiting for them.  The
553     * application is currently being launched and the provider will be
554     * removed from this list once it is published.
555     */
556    final ArrayList<ContentProviderRecord> mLaunchingProviders
557            = new ArrayList<ContentProviderRecord>();
558
559    /**
560     * Global set of specific Uri permissions that have been granted.
561     */
562    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
563            = new SparseArray<HashMap<Uri, UriPermission>>();
564
565    CoreSettingsObserver mCoreSettingsObserver;
566
567    /**
568     * Thread-local storage used to carry caller permissions over through
569     * indirect content-provider access.
570     * @see #ActivityManagerService.openContentUri()
571     */
572    private class Identity {
573        public int pid;
574        public int uid;
575
576        Identity(int _pid, int _uid) {
577            pid = _pid;
578            uid = _uid;
579        }
580    }
581
582    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
583
584    /**
585     * All information we have collected about the runtime performance of
586     * any user id that can impact battery performance.
587     */
588    final BatteryStatsService mBatteryStatsService;
589
590    /**
591     * information about component usage
592     */
593    final UsageStatsService mUsageStatsService;
594
595    /**
596     * Current configuration information.  HistoryRecord objects are given
597     * a reference to this object to indicate which configuration they are
598     * currently running in, so this object must be kept immutable.
599     */
600    Configuration mConfiguration = new Configuration();
601
602    /**
603     * Current sequencing integer of the configuration, for skipping old
604     * configurations.
605     */
606    int mConfigurationSeq = 0;
607
608    /**
609     * Hardware-reported OpenGLES version.
610     */
611    final int GL_ES_VERSION;
612
613    /**
614     * List of initialization arguments to pass to all processes when binding applications to them.
615     * For example, references to the commonly used services.
616     */
617    HashMap<String, IBinder> mAppBindArgs;
618
619    /**
620     * Temporary to avoid allocations.  Protected by main lock.
621     */
622    final StringBuilder mStringBuilder = new StringBuilder(256);
623
624    /**
625     * Used to control how we initialize the service.
626     */
627    boolean mStartRunning = false;
628    ComponentName mTopComponent;
629    String mTopAction;
630    String mTopData;
631    boolean mProcessesReady = false;
632    boolean mSystemReady = false;
633    boolean mBooting = false;
634    boolean mWaitingUpdate = false;
635    boolean mDidUpdate = false;
636    boolean mOnBattery = false;
637    boolean mLaunchWarningShown = false;
638
639    Context mContext;
640
641    int mFactoryTest;
642
643    boolean mCheckedForSetup;
644
645    /**
646     * The time at which we will allow normal application switches again,
647     * after a call to {@link #stopAppSwitches()}.
648     */
649    long mAppSwitchesAllowedTime;
650
651    /**
652     * This is set to true after the first switch after mAppSwitchesAllowedTime
653     * is set; any switches after that will clear the time.
654     */
655    boolean mDidAppSwitch;
656
657    /**
658     * Last time (in realtime) at which we checked for power usage.
659     */
660    long mLastPowerCheckRealtime;
661
662    /**
663     * Last time (in uptime) at which we checked for power usage.
664     */
665    long mLastPowerCheckUptime;
666
667    /**
668     * Set while we are wanting to sleep, to prevent any
669     * activities from being started/resumed.
670     */
671    boolean mSleeping = false;
672
673    /**
674     * State of external calls telling us if the device is asleep.
675     */
676    boolean mWentToSleep = false;
677
678    /**
679     * State of external call telling us if the lock screen is shown.
680     */
681    boolean mLockScreenShown = false;
682
683    /**
684     * Set if we are shutting down the system, similar to sleeping.
685     */
686    boolean mShuttingDown = false;
687
688    /**
689     * Task identifier that activities are currently being started
690     * in.  Incremented each time a new task is created.
691     * todo: Replace this with a TokenSpace class that generates non-repeating
692     * integers that won't wrap.
693     */
694    int mCurTask = 1;
695
696    /**
697     * Current sequence id for oom_adj computation traversal.
698     */
699    int mAdjSeq = 0;
700
701    /**
702     * Current sequence id for process LRU updating.
703     */
704    int mLruSeq = 0;
705
706    /**
707     * Keep track of the non-hidden/empty process we last found, to help
708     * determine how to distribute hidden/empty processes next time.
709     */
710    int mNumNonHiddenProcs = 0;
711
712    /**
713     * Keep track of the number of hidden procs, to balance oom adj
714     * distribution between those and empty procs.
715     */
716    int mNumHiddenProcs = 0;
717
718    /**
719     * Keep track of the number of service processes we last found, to
720     * determine on the next iteration which should be B services.
721     */
722    int mNumServiceProcs = 0;
723    int mNewNumServiceProcs = 0;
724
725    /**
726     * System monitoring: number of processes that died since the last
727     * N procs were started.
728     */
729    int[] mProcDeaths = new int[20];
730
731    /**
732     * This is set if we had to do a delayed dexopt of an app before launching
733     * it, to increasing the ANR timeouts in that case.
734     */
735    boolean mDidDexOpt;
736
737    String mDebugApp = null;
738    boolean mWaitForDebugger = false;
739    boolean mDebugTransient = false;
740    String mOrigDebugApp = null;
741    boolean mOrigWaitForDebugger = false;
742    boolean mAlwaysFinishActivities = false;
743    IActivityController mController = null;
744    String mProfileApp = null;
745    ProcessRecord mProfileProc = null;
746    String mProfileFile;
747    ParcelFileDescriptor mProfileFd;
748    int mProfileType = 0;
749    boolean mAutoStopProfiler = false;
750    String mOpenGlTraceApp = null;
751
752    static class ProcessChangeItem {
753        static final int CHANGE_ACTIVITIES = 1<<0;
754        static final int CHANGE_IMPORTANCE= 1<<1;
755        int changes;
756        int uid;
757        int pid;
758        int importance;
759        boolean foregroundActivities;
760    }
761
762    final RemoteCallbackList<IProcessObserver> mProcessObservers
763            = new RemoteCallbackList<IProcessObserver>();
764    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
765
766    final ArrayList<ProcessChangeItem> mPendingProcessChanges
767            = new ArrayList<ProcessChangeItem>();
768    final ArrayList<ProcessChangeItem> mAvailProcessChanges
769            = new ArrayList<ProcessChangeItem>();
770
771    /**
772     * Callback of last caller to {@link #requestPss}.
773     */
774    Runnable mRequestPssCallback;
775
776    /**
777     * Remaining processes for which we are waiting results from the last
778     * call to {@link #requestPss}.
779     */
780    final ArrayList<ProcessRecord> mRequestPssList
781            = new ArrayList<ProcessRecord>();
782
783    /**
784     * Runtime statistics collection thread.  This object's lock is used to
785     * protect all related state.
786     */
787    final Thread mProcessStatsThread;
788
789    /**
790     * Used to collect process stats when showing not responding dialog.
791     * Protected by mProcessStatsThread.
792     */
793    final ProcessStats mProcessStats = new ProcessStats(
794            MONITOR_THREAD_CPU_USAGE);
795    final AtomicLong mLastCpuTime = new AtomicLong(0);
796    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
797
798    long mLastWriteTime = 0;
799
800    /**
801     * Set to true after the system has finished booting.
802     */
803    boolean mBooted = false;
804
805    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
806    int mProcessLimitOverride = -1;
807
808    WindowManagerService mWindowManager;
809
810    static ActivityManagerService mSelf;
811    static ActivityThread mSystemThread;
812
813    private int mCurrentUserId;
814    private UserManager mUserManager;
815
816    private final class AppDeathRecipient implements IBinder.DeathRecipient {
817        final ProcessRecord mApp;
818        final int mPid;
819        final IApplicationThread mAppThread;
820
821        AppDeathRecipient(ProcessRecord app, int pid,
822                IApplicationThread thread) {
823            if (localLOGV) Slog.v(
824                TAG, "New death recipient " + this
825                + " for thread " + thread.asBinder());
826            mApp = app;
827            mPid = pid;
828            mAppThread = thread;
829        }
830
831        public void binderDied() {
832            if (localLOGV) Slog.v(
833                TAG, "Death received in " + this
834                + " for thread " + mAppThread.asBinder());
835            synchronized(ActivityManagerService.this) {
836                appDiedLocked(mApp, mPid, mAppThread);
837            }
838        }
839    }
840
841    static final int SHOW_ERROR_MSG = 1;
842    static final int SHOW_NOT_RESPONDING_MSG = 2;
843    static final int SHOW_FACTORY_ERROR_MSG = 3;
844    static final int UPDATE_CONFIGURATION_MSG = 4;
845    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
846    static final int WAIT_FOR_DEBUGGER_MSG = 6;
847    static final int SERVICE_TIMEOUT_MSG = 12;
848    static final int UPDATE_TIME_ZONE = 13;
849    static final int SHOW_UID_ERROR_MSG = 14;
850    static final int IM_FEELING_LUCKY_MSG = 15;
851    static final int PROC_START_TIMEOUT_MSG = 20;
852    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
853    static final int KILL_APPLICATION_MSG = 22;
854    static final int FINALIZE_PENDING_INTENT_MSG = 23;
855    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
856    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
857    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
858    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
859    static final int CLEAR_DNS_CACHE = 28;
860    static final int UPDATE_HTTP_PROXY = 29;
861    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
862    static final int DISPATCH_PROCESSES_CHANGED = 31;
863    static final int DISPATCH_PROCESS_DIED = 32;
864    static final int REPORT_MEM_USAGE = 33;
865
866    static final int FIRST_ACTIVITY_STACK_MSG = 100;
867    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
868    static final int FIRST_COMPAT_MODE_MSG = 300;
869
870    AlertDialog mUidAlert;
871    CompatModeDialog mCompatModeDialog;
872    long mLastMemUsageReportTime = 0;
873
874    final Handler mHandler = new Handler() {
875        //public Handler() {
876        //    if (localLOGV) Slog.v(TAG, "Handler started!");
877        //}
878
879        public void handleMessage(Message msg) {
880            switch (msg.what) {
881            case SHOW_ERROR_MSG: {
882                HashMap data = (HashMap) msg.obj;
883                synchronized (ActivityManagerService.this) {
884                    ProcessRecord proc = (ProcessRecord)data.get("app");
885                    if (proc != null && proc.crashDialog != null) {
886                        Slog.e(TAG, "App already has crash dialog: " + proc);
887                        return;
888                    }
889                    AppErrorResult res = (AppErrorResult) data.get("result");
890                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
891                        Dialog d = new AppErrorDialog(mContext, res, proc);
892                        d.show();
893                        proc.crashDialog = d;
894                    } else {
895                        // The device is asleep, so just pretend that the user
896                        // saw a crash dialog and hit "force quit".
897                        res.set(0);
898                    }
899                }
900
901                ensureBootCompleted();
902            } break;
903            case SHOW_NOT_RESPONDING_MSG: {
904                synchronized (ActivityManagerService.this) {
905                    HashMap data = (HashMap) msg.obj;
906                    ProcessRecord proc = (ProcessRecord)data.get("app");
907                    if (proc != null && proc.anrDialog != null) {
908                        Slog.e(TAG, "App already has anr dialog: " + proc);
909                        return;
910                    }
911
912                    Intent intent = new Intent("android.intent.action.ANR");
913                    if (!mProcessesReady) {
914                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
915                                | Intent.FLAG_RECEIVER_FOREGROUND);
916                    }
917                    broadcastIntentLocked(null, null, intent,
918                            null, null, 0, null, null, null,
919                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
920
921                    if (mShowDialogs) {
922                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
923                                mContext, proc, (ActivityRecord)data.get("activity"));
924                        d.show();
925                        proc.anrDialog = d;
926                    } else {
927                        // Just kill the app if there is no dialog to be shown.
928                        killAppAtUsersRequest(proc, null);
929                    }
930                }
931
932                ensureBootCompleted();
933            } break;
934            case SHOW_STRICT_MODE_VIOLATION_MSG: {
935                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
936                synchronized (ActivityManagerService.this) {
937                    ProcessRecord proc = (ProcessRecord) data.get("app");
938                    if (proc == null) {
939                        Slog.e(TAG, "App not found when showing strict mode dialog.");
940                        break;
941                    }
942                    if (proc.crashDialog != null) {
943                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
944                        return;
945                    }
946                    AppErrorResult res = (AppErrorResult) data.get("result");
947                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
948                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
949                        d.show();
950                        proc.crashDialog = d;
951                    } else {
952                        // The device is asleep, so just pretend that the user
953                        // saw a crash dialog and hit "force quit".
954                        res.set(0);
955                    }
956                }
957                ensureBootCompleted();
958            } break;
959            case SHOW_FACTORY_ERROR_MSG: {
960                Dialog d = new FactoryErrorDialog(
961                    mContext, msg.getData().getCharSequence("msg"));
962                d.show();
963                ensureBootCompleted();
964            } break;
965            case UPDATE_CONFIGURATION_MSG: {
966                final ContentResolver resolver = mContext.getContentResolver();
967                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
968            } break;
969            case GC_BACKGROUND_PROCESSES_MSG: {
970                synchronized (ActivityManagerService.this) {
971                    performAppGcsIfAppropriateLocked();
972                }
973            } break;
974            case WAIT_FOR_DEBUGGER_MSG: {
975                synchronized (ActivityManagerService.this) {
976                    ProcessRecord app = (ProcessRecord)msg.obj;
977                    if (msg.arg1 != 0) {
978                        if (!app.waitedForDebugger) {
979                            Dialog d = new AppWaitingForDebuggerDialog(
980                                    ActivityManagerService.this,
981                                    mContext, app);
982                            app.waitDialog = d;
983                            app.waitedForDebugger = true;
984                            d.show();
985                        }
986                    } else {
987                        if (app.waitDialog != null) {
988                            app.waitDialog.dismiss();
989                            app.waitDialog = null;
990                        }
991                    }
992                }
993            } break;
994            case SERVICE_TIMEOUT_MSG: {
995                if (mDidDexOpt) {
996                    mDidDexOpt = false;
997                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
998                    nmsg.obj = msg.obj;
999                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1000                    return;
1001                }
1002                mServices.serviceTimeout((ProcessRecord)msg.obj);
1003            } break;
1004            case UPDATE_TIME_ZONE: {
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.updateTimeZone();
1011                            } catch (RemoteException ex) {
1012                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1013                            }
1014                        }
1015                    }
1016                }
1017            } break;
1018            case CLEAR_DNS_CACHE: {
1019                synchronized (ActivityManagerService.this) {
1020                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1021                        ProcessRecord r = mLruProcesses.get(i);
1022                        if (r.thread != null) {
1023                            try {
1024                                r.thread.clearDnsCache();
1025                            } catch (RemoteException ex) {
1026                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1027                            }
1028                        }
1029                    }
1030                }
1031            } break;
1032            case UPDATE_HTTP_PROXY: {
1033                ProxyProperties proxy = (ProxyProperties)msg.obj;
1034                String host = "";
1035                String port = "";
1036                String exclList = "";
1037                if (proxy != null) {
1038                    host = proxy.getHost();
1039                    port = Integer.toString(proxy.getPort());
1040                    exclList = proxy.getExclusionList();
1041                }
1042                synchronized (ActivityManagerService.this) {
1043                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1044                        ProcessRecord r = mLruProcesses.get(i);
1045                        if (r.thread != null) {
1046                            try {
1047                                r.thread.setHttpProxy(host, port, exclList);
1048                            } catch (RemoteException ex) {
1049                                Slog.w(TAG, "Failed to update http proxy for: " +
1050                                        r.info.processName);
1051                            }
1052                        }
1053                    }
1054                }
1055            } break;
1056            case SHOW_UID_ERROR_MSG: {
1057                String title = "System UIDs Inconsistent";
1058                String text = "UIDs on the system are inconsistent, you need to wipe your"
1059                        + " data partition or your device will be unstable.";
1060                Log.e(TAG, title + ": " + text);
1061                if (mShowDialogs) {
1062                    // XXX This is a temporary dialog, no need to localize.
1063                    AlertDialog d = new BaseErrorDialog(mContext);
1064                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1065                    d.setCancelable(false);
1066                    d.setTitle(title);
1067                    d.setMessage(text);
1068                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1069                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1070                    mUidAlert = d;
1071                    d.show();
1072                }
1073            } break;
1074            case IM_FEELING_LUCKY_MSG: {
1075                if (mUidAlert != null) {
1076                    mUidAlert.dismiss();
1077                    mUidAlert = null;
1078                }
1079            } break;
1080            case PROC_START_TIMEOUT_MSG: {
1081                if (mDidDexOpt) {
1082                    mDidDexOpt = false;
1083                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1084                    nmsg.obj = msg.obj;
1085                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1086                    return;
1087                }
1088                ProcessRecord app = (ProcessRecord)msg.obj;
1089                synchronized (ActivityManagerService.this) {
1090                    processStartTimedOutLocked(app);
1091                }
1092            } break;
1093            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1094                synchronized (ActivityManagerService.this) {
1095                    doPendingActivityLaunchesLocked(true);
1096                }
1097            } break;
1098            case KILL_APPLICATION_MSG: {
1099                synchronized (ActivityManagerService.this) {
1100                    int appid = msg.arg1;
1101                    boolean restart = (msg.arg2 == 1);
1102                    String pkg = (String) msg.obj;
1103                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1104                            UserHandle.USER_ALL);
1105                }
1106            } break;
1107            case FINALIZE_PENDING_INTENT_MSG: {
1108                ((PendingIntentRecord)msg.obj).completeFinalize();
1109            } break;
1110            case POST_HEAVY_NOTIFICATION_MSG: {
1111                INotificationManager inm = NotificationManager.getService();
1112                if (inm == null) {
1113                    return;
1114                }
1115
1116                ActivityRecord root = (ActivityRecord)msg.obj;
1117                ProcessRecord process = root.app;
1118                if (process == null) {
1119                    return;
1120                }
1121
1122                try {
1123                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1124                    String text = mContext.getString(R.string.heavy_weight_notification,
1125                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1126                    Notification notification = new Notification();
1127                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1128                    notification.when = 0;
1129                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1130                    notification.tickerText = text;
1131                    notification.defaults = 0; // please be quiet
1132                    notification.sound = null;
1133                    notification.vibrate = null;
1134                    notification.setLatestEventInfo(context, text,
1135                            mContext.getText(R.string.heavy_weight_notification_detail),
1136                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1137                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1138                                    new UserHandle(root.userId)));
1139
1140                    try {
1141                        int[] outId = new int[1];
1142                        inm.enqueueNotificationWithTag("android", null,
1143                                R.string.heavy_weight_notification,
1144                                notification, outId, root.userId);
1145                    } catch (RuntimeException e) {
1146                        Slog.w(ActivityManagerService.TAG,
1147                                "Error showing notification for heavy-weight app", e);
1148                    } catch (RemoteException e) {
1149                    }
1150                } catch (NameNotFoundException e) {
1151                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1152                }
1153            } break;
1154            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1155                INotificationManager inm = NotificationManager.getService();
1156                if (inm == null) {
1157                    return;
1158                }
1159                try {
1160                    inm.cancelNotificationWithTag("android", null,
1161                            R.string.heavy_weight_notification,  msg.arg1);
1162                } catch (RuntimeException e) {
1163                    Slog.w(ActivityManagerService.TAG,
1164                            "Error canceling notification for service", e);
1165                } catch (RemoteException e) {
1166                }
1167            } break;
1168            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1169                synchronized (ActivityManagerService.this) {
1170                    checkExcessivePowerUsageLocked(true);
1171                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1172                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1173                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1174                }
1175            } break;
1176            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1177                synchronized (ActivityManagerService.this) {
1178                    ActivityRecord ar = (ActivityRecord)msg.obj;
1179                    if (mCompatModeDialog != null) {
1180                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1181                                ar.info.applicationInfo.packageName)) {
1182                            return;
1183                        }
1184                        mCompatModeDialog.dismiss();
1185                        mCompatModeDialog = null;
1186                    }
1187                    if (ar != null && false) {
1188                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1189                                ar.packageName)) {
1190                            int mode = mCompatModePackages.computeCompatModeLocked(
1191                                    ar.info.applicationInfo);
1192                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1193                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1194                                mCompatModeDialog = new CompatModeDialog(
1195                                        ActivityManagerService.this, mContext,
1196                                        ar.info.applicationInfo);
1197                                mCompatModeDialog.show();
1198                            }
1199                        }
1200                    }
1201                }
1202                break;
1203            }
1204            case DISPATCH_PROCESSES_CHANGED: {
1205                dispatchProcessesChanged();
1206                break;
1207            }
1208            case DISPATCH_PROCESS_DIED: {
1209                final int pid = msg.arg1;
1210                final int uid = msg.arg2;
1211                dispatchProcessDied(pid, uid);
1212                break;
1213            }
1214            case REPORT_MEM_USAGE: {
1215                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1216                if (!isDebuggable) {
1217                    return;
1218                }
1219                synchronized (ActivityManagerService.this) {
1220                    long now = SystemClock.uptimeMillis();
1221                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1222                        // Don't report more than every 5 minutes to somewhat
1223                        // avoid spamming.
1224                        return;
1225                    }
1226                    mLastMemUsageReportTime = now;
1227                }
1228                Thread thread = new Thread() {
1229                    @Override public void run() {
1230                        StringBuilder dropBuilder = new StringBuilder(1024);
1231                        StringBuilder logBuilder = new StringBuilder(1024);
1232                        StringWriter oomSw = new StringWriter();
1233                        PrintWriter oomPw = new PrintWriter(oomSw);
1234                        StringWriter catSw = new StringWriter();
1235                        PrintWriter catPw = new PrintWriter(catSw);
1236                        String[] emptyArgs = new String[] { };
1237                        StringBuilder tag = new StringBuilder(128);
1238                        StringBuilder stack = new StringBuilder(128);
1239                        tag.append("Low on memory -- ");
1240                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1241                                tag, stack);
1242                        dropBuilder.append(stack);
1243                        dropBuilder.append('\n');
1244                        dropBuilder.append('\n');
1245                        String oomString = oomSw.toString();
1246                        dropBuilder.append(oomString);
1247                        dropBuilder.append('\n');
1248                        logBuilder.append(oomString);
1249                        try {
1250                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1251                                    "procrank", });
1252                            final InputStreamReader converter = new InputStreamReader(
1253                                    proc.getInputStream());
1254                            BufferedReader in = new BufferedReader(converter);
1255                            String line;
1256                            while (true) {
1257                                line = in.readLine();
1258                                if (line == null) {
1259                                    break;
1260                                }
1261                                if (line.length() > 0) {
1262                                    logBuilder.append(line);
1263                                    logBuilder.append('\n');
1264                                }
1265                                dropBuilder.append(line);
1266                                dropBuilder.append('\n');
1267                            }
1268                            converter.close();
1269                        } catch (IOException e) {
1270                        }
1271                        synchronized (ActivityManagerService.this) {
1272                            catPw.println();
1273                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1274                            catPw.println();
1275                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1276                                    false, false, null);
1277                            catPw.println();
1278                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1279                        }
1280                        dropBuilder.append(catSw.toString());
1281                        addErrorToDropBox("lowmem", null, "system_server", null,
1282                                null, tag.toString(), dropBuilder.toString(), null, null);
1283                        Slog.i(TAG, logBuilder.toString());
1284                        synchronized (ActivityManagerService.this) {
1285                            long now = SystemClock.uptimeMillis();
1286                            if (mLastMemUsageReportTime < now) {
1287                                mLastMemUsageReportTime = now;
1288                            }
1289                        }
1290                    }
1291                };
1292                thread.start();
1293                break;
1294            }
1295            }
1296        }
1297    };
1298
1299    public static void setSystemProcess() {
1300        try {
1301            ActivityManagerService m = mSelf;
1302
1303            ServiceManager.addService("activity", m, true);
1304            ServiceManager.addService("meminfo", new MemBinder(m));
1305            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1306            ServiceManager.addService("dbinfo", new DbBinder(m));
1307            if (MONITOR_CPU_USAGE) {
1308                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1309            }
1310            ServiceManager.addService("permission", new PermissionController(m));
1311
1312            ApplicationInfo info =
1313                mSelf.mContext.getPackageManager().getApplicationInfo(
1314                            "android", STOCK_PM_FLAGS);
1315            mSystemThread.installSystemApplicationInfo(info);
1316
1317            synchronized (mSelf) {
1318                ProcessRecord app = mSelf.newProcessRecordLocked(
1319                        mSystemThread.getApplicationThread(), info,
1320                        info.processName, false);
1321                app.persistent = true;
1322                app.pid = MY_PID;
1323                app.maxAdj = ProcessList.SYSTEM_ADJ;
1324                mSelf.mProcessNames.put(app.processName, app.uid, app);
1325                synchronized (mSelf.mPidsSelfLocked) {
1326                    mSelf.mPidsSelfLocked.put(app.pid, app);
1327                }
1328                mSelf.updateLruProcessLocked(app, true, true);
1329            }
1330        } catch (PackageManager.NameNotFoundException e) {
1331            throw new RuntimeException(
1332                    "Unable to find android system package", e);
1333        }
1334    }
1335
1336    public void setWindowManager(WindowManagerService wm) {
1337        mWindowManager = wm;
1338    }
1339
1340    public static final Context main(int factoryTest) {
1341        AThread thr = new AThread();
1342        thr.start();
1343
1344        synchronized (thr) {
1345            while (thr.mService == null) {
1346                try {
1347                    thr.wait();
1348                } catch (InterruptedException e) {
1349                }
1350            }
1351        }
1352
1353        ActivityManagerService m = thr.mService;
1354        mSelf = m;
1355        ActivityThread at = ActivityThread.systemMain();
1356        mSystemThread = at;
1357        Context context = at.getSystemContext();
1358        context.setTheme(android.R.style.Theme_Holo);
1359        m.mContext = context;
1360        m.mFactoryTest = factoryTest;
1361        m.mMainStack = new ActivityStack(m, context, true);
1362
1363        m.mBatteryStatsService.publish(context);
1364        m.mUsageStatsService.publish(context);
1365
1366        synchronized (thr) {
1367            thr.mReady = true;
1368            thr.notifyAll();
1369        }
1370
1371        m.startRunning(null, null, null, null);
1372
1373        return context;
1374    }
1375
1376    public static ActivityManagerService self() {
1377        return mSelf;
1378    }
1379
1380    static class AThread extends Thread {
1381        ActivityManagerService mService;
1382        boolean mReady = false;
1383
1384        public AThread() {
1385            super("ActivityManager");
1386        }
1387
1388        public void run() {
1389            Looper.prepare();
1390
1391            android.os.Process.setThreadPriority(
1392                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1393            android.os.Process.setCanSelfBackground(false);
1394
1395            ActivityManagerService m = new ActivityManagerService();
1396
1397            synchronized (this) {
1398                mService = m;
1399                notifyAll();
1400            }
1401
1402            synchronized (this) {
1403                while (!mReady) {
1404                    try {
1405                        wait();
1406                    } catch (InterruptedException e) {
1407                    }
1408                }
1409            }
1410
1411            // For debug builds, log event loop stalls to dropbox for analysis.
1412            if (StrictMode.conditionallyEnableDebugLogging()) {
1413                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1414            }
1415
1416            Looper.loop();
1417        }
1418    }
1419
1420    static class MemBinder extends Binder {
1421        ActivityManagerService mActivityManagerService;
1422        MemBinder(ActivityManagerService activityManagerService) {
1423            mActivityManagerService = activityManagerService;
1424        }
1425
1426        @Override
1427        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1428            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1429                    != PackageManager.PERMISSION_GRANTED) {
1430                pw.println("Permission Denial: can't dump meminfo from from pid="
1431                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1432                        + " without permission " + android.Manifest.permission.DUMP);
1433                return;
1434            }
1435
1436            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1437                    false, null, null, null);
1438        }
1439    }
1440
1441    static class GraphicsBinder extends Binder {
1442        ActivityManagerService mActivityManagerService;
1443        GraphicsBinder(ActivityManagerService activityManagerService) {
1444            mActivityManagerService = activityManagerService;
1445        }
1446
1447        @Override
1448        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1449            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1450                    != PackageManager.PERMISSION_GRANTED) {
1451                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1452                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1453                        + " without permission " + android.Manifest.permission.DUMP);
1454                return;
1455            }
1456
1457            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1458        }
1459    }
1460
1461    static class DbBinder extends Binder {
1462        ActivityManagerService mActivityManagerService;
1463        DbBinder(ActivityManagerService activityManagerService) {
1464            mActivityManagerService = activityManagerService;
1465        }
1466
1467        @Override
1468        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1469            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1470                    != PackageManager.PERMISSION_GRANTED) {
1471                pw.println("Permission Denial: can't dump dbinfo from from pid="
1472                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1473                        + " without permission " + android.Manifest.permission.DUMP);
1474                return;
1475            }
1476
1477            mActivityManagerService.dumpDbInfo(fd, pw, args);
1478        }
1479    }
1480
1481    static class CpuBinder extends Binder {
1482        ActivityManagerService mActivityManagerService;
1483        CpuBinder(ActivityManagerService activityManagerService) {
1484            mActivityManagerService = activityManagerService;
1485        }
1486
1487        @Override
1488        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1489            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1490                    != PackageManager.PERMISSION_GRANTED) {
1491                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1492                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1493                        + " without permission " + android.Manifest.permission.DUMP);
1494                return;
1495            }
1496
1497            synchronized (mActivityManagerService.mProcessStatsThread) {
1498                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1499                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1500                        SystemClock.uptimeMillis()));
1501            }
1502        }
1503    }
1504
1505    private ActivityManagerService() {
1506        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1507
1508        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1509        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1510        mBroadcastQueues[0] = mFgBroadcastQueue;
1511        mBroadcastQueues[1] = mBgBroadcastQueue;
1512
1513        mServices = new ActiveServices(this);
1514        mProviderMap = new ProviderMap(this);
1515
1516        File dataDir = Environment.getDataDirectory();
1517        File systemDir = new File(dataDir, "system");
1518        systemDir.mkdirs();
1519        mBatteryStatsService = new BatteryStatsService(new File(
1520                systemDir, "batterystats.bin").toString());
1521        mBatteryStatsService.getActiveStatistics().readLocked();
1522        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1523        mOnBattery = DEBUG_POWER ? true
1524                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1525        mBatteryStatsService.getActiveStatistics().setCallback(this);
1526
1527        mUsageStatsService = new UsageStatsService(new File(
1528                systemDir, "usagestats").toString());
1529        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1530
1531        // User 0 is the first and only user that runs at boot.
1532        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1533        mUserLru.add(Integer.valueOf(0));
1534
1535        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1536            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1537
1538        mConfiguration.setToDefaults();
1539        mConfiguration.setLocale(Locale.getDefault());
1540
1541        mConfigurationSeq = mConfiguration.seq = 1;
1542        mProcessStats.init();
1543
1544        mCompatModePackages = new CompatModePackages(this, systemDir);
1545
1546        // Add ourself to the Watchdog monitors.
1547        Watchdog.getInstance().addMonitor(this);
1548
1549        mProcessStatsThread = new Thread("ProcessStats") {
1550            public void run() {
1551                while (true) {
1552                    try {
1553                        try {
1554                            synchronized(this) {
1555                                final long now = SystemClock.uptimeMillis();
1556                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1557                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1558                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1559                                //        + ", write delay=" + nextWriteDelay);
1560                                if (nextWriteDelay < nextCpuDelay) {
1561                                    nextCpuDelay = nextWriteDelay;
1562                                }
1563                                if (nextCpuDelay > 0) {
1564                                    mProcessStatsMutexFree.set(true);
1565                                    this.wait(nextCpuDelay);
1566                                }
1567                            }
1568                        } catch (InterruptedException e) {
1569                        }
1570                        updateCpuStatsNow();
1571                    } catch (Exception e) {
1572                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1573                    }
1574                }
1575            }
1576        };
1577        mProcessStatsThread.start();
1578    }
1579
1580    @Override
1581    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1582            throws RemoteException {
1583        if (code == SYSPROPS_TRANSACTION) {
1584            // We need to tell all apps about the system property change.
1585            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1586            synchronized(this) {
1587                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1588                    final int NA = apps.size();
1589                    for (int ia=0; ia<NA; ia++) {
1590                        ProcessRecord app = apps.valueAt(ia);
1591                        if (app.thread != null) {
1592                            procs.add(app.thread.asBinder());
1593                        }
1594                    }
1595                }
1596            }
1597
1598            int N = procs.size();
1599            for (int i=0; i<N; i++) {
1600                Parcel data2 = Parcel.obtain();
1601                try {
1602                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1603                } catch (RemoteException e) {
1604                }
1605                data2.recycle();
1606            }
1607        }
1608        try {
1609            return super.onTransact(code, data, reply, flags);
1610        } catch (RuntimeException e) {
1611            // The activity manager only throws security exceptions, so let's
1612            // log all others.
1613            if (!(e instanceof SecurityException)) {
1614                Slog.e(TAG, "Activity Manager Crash", e);
1615            }
1616            throw e;
1617        }
1618    }
1619
1620    void updateCpuStats() {
1621        final long now = SystemClock.uptimeMillis();
1622        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1623            return;
1624        }
1625        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1626            synchronized (mProcessStatsThread) {
1627                mProcessStatsThread.notify();
1628            }
1629        }
1630    }
1631
1632    void updateCpuStatsNow() {
1633        synchronized (mProcessStatsThread) {
1634            mProcessStatsMutexFree.set(false);
1635            final long now = SystemClock.uptimeMillis();
1636            boolean haveNewCpuStats = false;
1637
1638            if (MONITOR_CPU_USAGE &&
1639                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1640                mLastCpuTime.set(now);
1641                haveNewCpuStats = true;
1642                mProcessStats.update();
1643                //Slog.i(TAG, mProcessStats.printCurrentState());
1644                //Slog.i(TAG, "Total CPU usage: "
1645                //        + mProcessStats.getTotalCpuPercent() + "%");
1646
1647                // Slog the cpu usage if the property is set.
1648                if ("true".equals(SystemProperties.get("events.cpu"))) {
1649                    int user = mProcessStats.getLastUserTime();
1650                    int system = mProcessStats.getLastSystemTime();
1651                    int iowait = mProcessStats.getLastIoWaitTime();
1652                    int irq = mProcessStats.getLastIrqTime();
1653                    int softIrq = mProcessStats.getLastSoftIrqTime();
1654                    int idle = mProcessStats.getLastIdleTime();
1655
1656                    int total = user + system + iowait + irq + softIrq + idle;
1657                    if (total == 0) total = 1;
1658
1659                    EventLog.writeEvent(EventLogTags.CPU,
1660                            ((user+system+iowait+irq+softIrq) * 100) / total,
1661                            (user * 100) / total,
1662                            (system * 100) / total,
1663                            (iowait * 100) / total,
1664                            (irq * 100) / total,
1665                            (softIrq * 100) / total);
1666                }
1667            }
1668
1669            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1670            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1671            synchronized(bstats) {
1672                synchronized(mPidsSelfLocked) {
1673                    if (haveNewCpuStats) {
1674                        if (mOnBattery) {
1675                            int perc = bstats.startAddingCpuLocked();
1676                            int totalUTime = 0;
1677                            int totalSTime = 0;
1678                            final int N = mProcessStats.countStats();
1679                            for (int i=0; i<N; i++) {
1680                                ProcessStats.Stats st = mProcessStats.getStats(i);
1681                                if (!st.working) {
1682                                    continue;
1683                                }
1684                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1685                                int otherUTime = (st.rel_utime*perc)/100;
1686                                int otherSTime = (st.rel_stime*perc)/100;
1687                                totalUTime += otherUTime;
1688                                totalSTime += otherSTime;
1689                                if (pr != null) {
1690                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1691                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1692                                            st.rel_stime-otherSTime);
1693                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1694                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1695                                } else {
1696                                    BatteryStatsImpl.Uid.Proc ps =
1697                                            bstats.getProcessStatsLocked(st.name, st.pid);
1698                                    if (ps != null) {
1699                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1700                                                st.rel_stime-otherSTime);
1701                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1702                                    }
1703                                }
1704                            }
1705                            bstats.finishAddingCpuLocked(perc, totalUTime,
1706                                    totalSTime, cpuSpeedTimes);
1707                        }
1708                    }
1709                }
1710
1711                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1712                    mLastWriteTime = now;
1713                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1714                }
1715            }
1716        }
1717    }
1718
1719    @Override
1720    public void batteryNeedsCpuUpdate() {
1721        updateCpuStatsNow();
1722    }
1723
1724    @Override
1725    public void batteryPowerChanged(boolean onBattery) {
1726        // When plugging in, update the CPU stats first before changing
1727        // the plug state.
1728        updateCpuStatsNow();
1729        synchronized (this) {
1730            synchronized(mPidsSelfLocked) {
1731                mOnBattery = DEBUG_POWER ? true : onBattery;
1732            }
1733        }
1734    }
1735
1736    /**
1737     * Initialize the application bind args. These are passed to each
1738     * process when the bindApplication() IPC is sent to the process. They're
1739     * lazily setup to make sure the services are running when they're asked for.
1740     */
1741    private HashMap<String, IBinder> getCommonServicesLocked() {
1742        if (mAppBindArgs == null) {
1743            mAppBindArgs = new HashMap<String, IBinder>();
1744
1745            // Setup the application init args
1746            mAppBindArgs.put("package", ServiceManager.getService("package"));
1747            mAppBindArgs.put("window", ServiceManager.getService("window"));
1748            mAppBindArgs.put(Context.ALARM_SERVICE,
1749                    ServiceManager.getService(Context.ALARM_SERVICE));
1750        }
1751        return mAppBindArgs;
1752    }
1753
1754    final void setFocusedActivityLocked(ActivityRecord r) {
1755        if (mFocusedActivity != r) {
1756            mFocusedActivity = r;
1757            if (r != null) {
1758                mWindowManager.setFocusedApp(r.appToken, true);
1759            }
1760        }
1761    }
1762
1763    private final void updateLruProcessInternalLocked(ProcessRecord app,
1764            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1765        // put it on the LRU to keep track of when it should be exited.
1766        int lrui = mLruProcesses.indexOf(app);
1767        if (lrui >= 0) mLruProcesses.remove(lrui);
1768
1769        int i = mLruProcesses.size()-1;
1770        int skipTop = 0;
1771
1772        app.lruSeq = mLruSeq;
1773
1774        // compute the new weight for this process.
1775        if (updateActivityTime) {
1776            app.lastActivityTime = SystemClock.uptimeMillis();
1777        }
1778        if (app.activities.size() > 0) {
1779            // If this process has activities, we more strongly want to keep
1780            // it around.
1781            app.lruWeight = app.lastActivityTime;
1782        } else if (app.pubProviders.size() > 0) {
1783            // If this process contains content providers, we want to keep
1784            // it a little more strongly.
1785            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1786            // Also don't let it kick out the first few "real" hidden processes.
1787            skipTop = ProcessList.MIN_HIDDEN_APPS;
1788        } else {
1789            // If this process doesn't have activities, we less strongly
1790            // want to keep it around, and generally want to avoid getting
1791            // in front of any very recently used activities.
1792            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1793            // Also don't let it kick out the first few "real" hidden processes.
1794            skipTop = ProcessList.MIN_HIDDEN_APPS;
1795        }
1796
1797        while (i >= 0) {
1798            ProcessRecord p = mLruProcesses.get(i);
1799            // If this app shouldn't be in front of the first N background
1800            // apps, then skip over that many that are currently hidden.
1801            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1802                skipTop--;
1803            }
1804            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1805                mLruProcesses.add(i+1, app);
1806                break;
1807            }
1808            i--;
1809        }
1810        if (i < 0) {
1811            mLruProcesses.add(0, app);
1812        }
1813
1814        // If the app is currently using a content provider or service,
1815        // bump those processes as well.
1816        if (app.connections.size() > 0) {
1817            for (ConnectionRecord cr : app.connections) {
1818                if (cr.binding != null && cr.binding.service != null
1819                        && cr.binding.service.app != null
1820                        && cr.binding.service.app.lruSeq != mLruSeq) {
1821                    updateLruProcessInternalLocked(cr.binding.service.app, false,
1822                            updateActivityTime, i+1);
1823                }
1824            }
1825        }
1826        for (int j=app.conProviders.size()-1; j>=0; j--) {
1827            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1828            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1829                updateLruProcessInternalLocked(cpr.proc, false,
1830                        updateActivityTime, i+1);
1831            }
1832        }
1833
1834        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1835        if (oomAdj) {
1836            updateOomAdjLocked();
1837        }
1838    }
1839
1840    final void updateLruProcessLocked(ProcessRecord app,
1841            boolean oomAdj, boolean updateActivityTime) {
1842        mLruSeq++;
1843        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1844    }
1845
1846    final ProcessRecord getProcessRecordLocked(
1847            String processName, int uid) {
1848        if (uid == Process.SYSTEM_UID) {
1849            // The system gets to run in any process.  If there are multiple
1850            // processes with the same uid, just pick the first (this
1851            // should never happen).
1852            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1853                    processName);
1854            if (procs == null) return null;
1855            final int N = procs.size();
1856            for (int i = 0; i < N; i++) {
1857                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1858            }
1859        }
1860        ProcessRecord proc = mProcessNames.get(processName, uid);
1861        return proc;
1862    }
1863
1864    void ensurePackageDexOpt(String packageName) {
1865        IPackageManager pm = AppGlobals.getPackageManager();
1866        try {
1867            if (pm.performDexOpt(packageName)) {
1868                mDidDexOpt = true;
1869            }
1870        } catch (RemoteException e) {
1871        }
1872    }
1873
1874    boolean isNextTransitionForward() {
1875        int transit = mWindowManager.getPendingAppTransition();
1876        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1877                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1878                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1879    }
1880
1881    final ProcessRecord startProcessLocked(String processName,
1882            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1883            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1884            boolean isolated) {
1885        ProcessRecord app;
1886        if (!isolated) {
1887            app = getProcessRecordLocked(processName, info.uid);
1888        } else {
1889            // If this is an isolated process, it can't re-use an existing process.
1890            app = null;
1891        }
1892        // We don't have to do anything more if:
1893        // (1) There is an existing application record; and
1894        // (2) The caller doesn't think it is dead, OR there is no thread
1895        //     object attached to it so we know it couldn't have crashed; and
1896        // (3) There is a pid assigned to it, so it is either starting or
1897        //     already running.
1898        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1899                + " app=" + app + " knownToBeDead=" + knownToBeDead
1900                + " thread=" + (app != null ? app.thread : null)
1901                + " pid=" + (app != null ? app.pid : -1));
1902        if (app != null && app.pid > 0) {
1903            if (!knownToBeDead || app.thread == null) {
1904                // We already have the app running, or are waiting for it to
1905                // come up (we have a pid but not yet its thread), so keep it.
1906                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1907                // If this is a new package in the process, add the package to the list
1908                app.addPackage(info.packageName);
1909                return app;
1910            } else {
1911                // An application record is attached to a previous process,
1912                // clean it up now.
1913                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1914                handleAppDiedLocked(app, true, true);
1915            }
1916        }
1917
1918        String hostingNameStr = hostingName != null
1919                ? hostingName.flattenToShortString() : null;
1920
1921        if (!isolated) {
1922            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1923                // If we are in the background, then check to see if this process
1924                // is bad.  If so, we will just silently fail.
1925                if (mBadProcesses.get(info.processName, info.uid) != null) {
1926                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1927                            + "/" + info.processName);
1928                    return null;
1929                }
1930            } else {
1931                // When the user is explicitly starting a process, then clear its
1932                // crash count so that we won't make it bad until they see at
1933                // least one crash dialog again, and make the process good again
1934                // if it had been bad.
1935                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1936                        + "/" + info.processName);
1937                mProcessCrashTimes.remove(info.processName, info.uid);
1938                if (mBadProcesses.get(info.processName, info.uid) != null) {
1939                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1940                            info.processName);
1941                    mBadProcesses.remove(info.processName, info.uid);
1942                    if (app != null) {
1943                        app.bad = false;
1944                    }
1945                }
1946            }
1947        }
1948
1949        if (app == null) {
1950            app = newProcessRecordLocked(null, info, processName, isolated);
1951            if (app == null) {
1952                Slog.w(TAG, "Failed making new process record for "
1953                        + processName + "/" + info.uid + " isolated=" + isolated);
1954                return null;
1955            }
1956            mProcessNames.put(processName, app.uid, app);
1957            if (isolated) {
1958                mIsolatedProcesses.put(app.uid, app);
1959            }
1960        } else {
1961            // If this is a new package in the process, add the package to the list
1962            app.addPackage(info.packageName);
1963        }
1964
1965        // If the system is not ready yet, then hold off on starting this
1966        // process until it is.
1967        if (!mProcessesReady
1968                && !isAllowedWhileBooting(info)
1969                && !allowWhileBooting) {
1970            if (!mProcessesOnHold.contains(app)) {
1971                mProcessesOnHold.add(app);
1972            }
1973            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1974            return app;
1975        }
1976
1977        startProcessLocked(app, hostingType, hostingNameStr);
1978        return (app.pid != 0) ? app : null;
1979    }
1980
1981    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1982        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1983    }
1984
1985    private final void startProcessLocked(ProcessRecord app,
1986            String hostingType, String hostingNameStr) {
1987        if (app.pid > 0 && app.pid != MY_PID) {
1988            synchronized (mPidsSelfLocked) {
1989                mPidsSelfLocked.remove(app.pid);
1990                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1991            }
1992            app.setPid(0);
1993        }
1994
1995        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1996                "startProcessLocked removing on hold: " + app);
1997        mProcessesOnHold.remove(app);
1998
1999        updateCpuStats();
2000
2001        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2002        mProcDeaths[0] = 0;
2003
2004        try {
2005            int uid = app.uid;
2006
2007            int[] gids = null;
2008            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2009            if (!app.isolated) {
2010                try {
2011                    final PackageManager pm = mContext.getPackageManager();
2012                    gids = pm.getPackageGids(app.info.packageName);
2013
2014                    if (Environment.isExternalStorageEmulated()) {
2015                        if (pm.checkPermission(
2016                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2017                                app.info.packageName) == PERMISSION_GRANTED) {
2018                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2019                        } else {
2020                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2021                        }
2022                    }
2023                } catch (PackageManager.NameNotFoundException e) {
2024                    Slog.w(TAG, "Unable to retrieve gids", e);
2025                }
2026            }
2027            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2028                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2029                        && mTopComponent != null
2030                        && app.processName.equals(mTopComponent.getPackageName())) {
2031                    uid = 0;
2032                }
2033                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2034                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2035                    uid = 0;
2036                }
2037            }
2038            int debugFlags = 0;
2039            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2040                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2041                // Also turn on CheckJNI for debuggable apps. It's quite
2042                // awkward to turn on otherwise.
2043                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2044            }
2045            // Run the app in safe mode if its manifest requests so or the
2046            // system is booted in safe mode.
2047            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2048                Zygote.systemInSafeMode == true) {
2049                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2050            }
2051            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2052                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2053            }
2054            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2055                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2056            }
2057            if ("1".equals(SystemProperties.get("debug.assert"))) {
2058                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2059            }
2060
2061            // Start the process.  It will either succeed and return a result containing
2062            // the PID of the new process, or else throw a RuntimeException.
2063            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2064                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2065                    app.info.targetSdkVersion, null, null);
2066
2067            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2068            synchronized (bs) {
2069                if (bs.isOnBattery()) {
2070                    app.batteryStats.incStartsLocked();
2071                }
2072            }
2073
2074            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2075                    app.processName, hostingType,
2076                    hostingNameStr != null ? hostingNameStr : "");
2077
2078            if (app.persistent) {
2079                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2080            }
2081
2082            StringBuilder buf = mStringBuilder;
2083            buf.setLength(0);
2084            buf.append("Start proc ");
2085            buf.append(app.processName);
2086            buf.append(" for ");
2087            buf.append(hostingType);
2088            if (hostingNameStr != null) {
2089                buf.append(" ");
2090                buf.append(hostingNameStr);
2091            }
2092            buf.append(": pid=");
2093            buf.append(startResult.pid);
2094            buf.append(" uid=");
2095            buf.append(uid);
2096            buf.append(" gids={");
2097            if (gids != null) {
2098                for (int gi=0; gi<gids.length; gi++) {
2099                    if (gi != 0) buf.append(", ");
2100                    buf.append(gids[gi]);
2101
2102                }
2103            }
2104            buf.append("}");
2105            Slog.i(TAG, buf.toString());
2106            app.setPid(startResult.pid);
2107            app.usingWrapper = startResult.usingWrapper;
2108            app.removed = false;
2109            synchronized (mPidsSelfLocked) {
2110                this.mPidsSelfLocked.put(startResult.pid, app);
2111                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2112                msg.obj = app;
2113                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2114                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2115            }
2116        } catch (RuntimeException e) {
2117            // XXX do better error recovery.
2118            app.setPid(0);
2119            Slog.e(TAG, "Failure starting process " + app.processName, e);
2120        }
2121    }
2122
2123    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2124        if (resumed) {
2125            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2126        } else {
2127            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2128        }
2129    }
2130
2131    boolean startHomeActivityLocked(int userId, UserStartedState startingUser) {
2132        if (mHeadless) {
2133            // Added because none of the other calls to ensureBootCompleted seem to fire
2134            // when running headless.
2135            ensureBootCompleted();
2136            return false;
2137        }
2138
2139        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2140                && mTopAction == null) {
2141            // We are running in factory test mode, but unable to find
2142            // the factory test app, so just sit around displaying the
2143            // error message and don't try to start anything.
2144            return false;
2145        }
2146        Intent intent = new Intent(
2147            mTopAction,
2148            mTopData != null ? Uri.parse(mTopData) : null);
2149        intent.setComponent(mTopComponent);
2150        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2151            intent.addCategory(Intent.CATEGORY_HOME);
2152        }
2153        ActivityInfo aInfo =
2154            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2155        if (aInfo != null) {
2156            intent.setComponent(new ComponentName(
2157                    aInfo.applicationInfo.packageName, aInfo.name));
2158            // Don't do this if the home app is currently being
2159            // instrumented.
2160            aInfo = new ActivityInfo(aInfo);
2161            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2162            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2163                    aInfo.applicationInfo.uid);
2164            if (app == null || app.instrumentationClass == null) {
2165                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2166                mMainStack.startActivityLocked(null, intent, null, aInfo,
2167                        null, null, 0, 0, 0, 0, null, false, null);
2168            }
2169        }
2170        if (startingUser != null) {
2171            mMainStack.addStartingUserLocked(startingUser);
2172        }
2173
2174        return true;
2175    }
2176
2177    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2178        ActivityInfo ai = null;
2179        ComponentName comp = intent.getComponent();
2180        try {
2181            if (comp != null) {
2182                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2183            } else {
2184                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2185                        intent,
2186                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2187                            flags, userId);
2188
2189                if (info != null) {
2190                    ai = info.activityInfo;
2191                }
2192            }
2193        } catch (RemoteException e) {
2194            // ignore
2195        }
2196
2197        return ai;
2198    }
2199
2200    /**
2201     * Starts the "new version setup screen" if appropriate.
2202     */
2203    void startSetupActivityLocked() {
2204        // Only do this once per boot.
2205        if (mCheckedForSetup) {
2206            return;
2207        }
2208
2209        // We will show this screen if the current one is a different
2210        // version than the last one shown, and we are not running in
2211        // low-level factory test mode.
2212        final ContentResolver resolver = mContext.getContentResolver();
2213        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2214                Settings.Secure.getInt(resolver,
2215                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2216            mCheckedForSetup = true;
2217
2218            // See if we should be showing the platform update setup UI.
2219            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2220            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2221                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2222
2223            // We don't allow third party apps to replace this.
2224            ResolveInfo ri = null;
2225            for (int i=0; ris != null && i<ris.size(); i++) {
2226                if ((ris.get(i).activityInfo.applicationInfo.flags
2227                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2228                    ri = ris.get(i);
2229                    break;
2230                }
2231            }
2232
2233            if (ri != null) {
2234                String vers = ri.activityInfo.metaData != null
2235                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2236                        : null;
2237                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2238                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2239                            Intent.METADATA_SETUP_VERSION);
2240                }
2241                String lastVers = Settings.Secure.getString(
2242                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2243                if (vers != null && !vers.equals(lastVers)) {
2244                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2245                    intent.setComponent(new ComponentName(
2246                            ri.activityInfo.packageName, ri.activityInfo.name));
2247                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2248                            null, null, 0, 0, 0, 0, null, false, null);
2249                }
2250            }
2251        }
2252    }
2253
2254    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2255        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2256    }
2257
2258    void enforceNotIsolatedCaller(String caller) {
2259        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2260            throw new SecurityException("Isolated process not allowed to call " + caller);
2261        }
2262    }
2263
2264    public int getFrontActivityScreenCompatMode() {
2265        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2266        synchronized (this) {
2267            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2268        }
2269    }
2270
2271    public void setFrontActivityScreenCompatMode(int mode) {
2272        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2273                "setFrontActivityScreenCompatMode");
2274        synchronized (this) {
2275            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2276        }
2277    }
2278
2279    public int getPackageScreenCompatMode(String packageName) {
2280        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2281        synchronized (this) {
2282            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2283        }
2284    }
2285
2286    public void setPackageScreenCompatMode(String packageName, int mode) {
2287        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2288                "setPackageScreenCompatMode");
2289        synchronized (this) {
2290            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2291        }
2292    }
2293
2294    public boolean getPackageAskScreenCompat(String packageName) {
2295        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2296        synchronized (this) {
2297            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2298        }
2299    }
2300
2301    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2302        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2303                "setPackageAskScreenCompat");
2304        synchronized (this) {
2305            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2306        }
2307    }
2308
2309    void reportResumedActivityLocked(ActivityRecord r) {
2310        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2311        updateUsageStats(r, true);
2312    }
2313
2314    private void dispatchProcessesChanged() {
2315        int N;
2316        synchronized (this) {
2317            N = mPendingProcessChanges.size();
2318            if (mActiveProcessChanges.length < N) {
2319                mActiveProcessChanges = new ProcessChangeItem[N];
2320            }
2321            mPendingProcessChanges.toArray(mActiveProcessChanges);
2322            mAvailProcessChanges.addAll(mPendingProcessChanges);
2323            mPendingProcessChanges.clear();
2324            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2325        }
2326        int i = mProcessObservers.beginBroadcast();
2327        while (i > 0) {
2328            i--;
2329            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2330            if (observer != null) {
2331                try {
2332                    for (int j=0; j<N; j++) {
2333                        ProcessChangeItem item = mActiveProcessChanges[j];
2334                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2335                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2336                                    + item.pid + " uid=" + item.uid + ": "
2337                                    + item.foregroundActivities);
2338                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2339                                    item.foregroundActivities);
2340                        }
2341                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2342                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2343                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2344                            observer.onImportanceChanged(item.pid, item.uid,
2345                                    item.importance);
2346                        }
2347                    }
2348                } catch (RemoteException e) {
2349                }
2350            }
2351        }
2352        mProcessObservers.finishBroadcast();
2353    }
2354
2355    private void dispatchProcessDied(int pid, int uid) {
2356        int i = mProcessObservers.beginBroadcast();
2357        while (i > 0) {
2358            i--;
2359            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2360            if (observer != null) {
2361                try {
2362                    observer.onProcessDied(pid, uid);
2363                } catch (RemoteException e) {
2364                }
2365            }
2366        }
2367        mProcessObservers.finishBroadcast();
2368    }
2369
2370    final void doPendingActivityLaunchesLocked(boolean doResume) {
2371        final int N = mPendingActivityLaunches.size();
2372        if (N <= 0) {
2373            return;
2374        }
2375        for (int i=0; i<N; i++) {
2376            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2377            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2378                    pal.startFlags, doResume && i == (N-1), null);
2379        }
2380        mPendingActivityLaunches.clear();
2381    }
2382
2383    public final int startActivity(IApplicationThread caller,
2384            Intent intent, String resolvedType, IBinder resultTo,
2385            String resultWho, int requestCode, int startFlags,
2386            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2387        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2388                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2389    }
2390
2391    public final int startActivityAsUser(IApplicationThread caller,
2392            Intent intent, String resolvedType, IBinder resultTo,
2393            String resultWho, int requestCode, int startFlags,
2394            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2395        enforceNotIsolatedCaller("startActivity");
2396        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2397                false, true, "startActivity", null);
2398        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2399                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2400                null, null, options, userId);
2401    }
2402
2403    public final WaitResult startActivityAndWait(IApplicationThread caller,
2404            Intent intent, String resolvedType, IBinder resultTo,
2405            String resultWho, int requestCode, int startFlags, String profileFile,
2406            ParcelFileDescriptor profileFd, Bundle options, int userId) {
2407        enforceNotIsolatedCaller("startActivityAndWait");
2408        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2409                false, true, "startActivityAndWait", null);
2410        WaitResult res = new WaitResult();
2411        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2412                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2413                res, null, options, UserHandle.getCallingUserId());
2414        return res;
2415    }
2416
2417    public final int startActivityWithConfig(IApplicationThread caller,
2418            Intent intent, String resolvedType, IBinder resultTo,
2419            String resultWho, int requestCode, int startFlags, Configuration config,
2420            Bundle options, int userId) {
2421        enforceNotIsolatedCaller("startActivityWithConfig");
2422        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2423                false, true, "startActivityWithConfig", null);
2424        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2425                resultTo, resultWho, requestCode, startFlags,
2426                null, null, null, config, options, userId);
2427        return ret;
2428    }
2429
2430    public int startActivityIntentSender(IApplicationThread caller,
2431            IntentSender intent, Intent fillInIntent, String resolvedType,
2432            IBinder resultTo, String resultWho, int requestCode,
2433            int flagsMask, int flagsValues, Bundle options) {
2434        enforceNotIsolatedCaller("startActivityIntentSender");
2435        // Refuse possible leaked file descriptors
2436        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2437            throw new IllegalArgumentException("File descriptors passed in Intent");
2438        }
2439
2440        IIntentSender sender = intent.getTarget();
2441        if (!(sender instanceof PendingIntentRecord)) {
2442            throw new IllegalArgumentException("Bad PendingIntent object");
2443        }
2444
2445        PendingIntentRecord pir = (PendingIntentRecord)sender;
2446
2447        synchronized (this) {
2448            // If this is coming from the currently resumed activity, it is
2449            // effectively saying that app switches are allowed at this point.
2450            if (mMainStack.mResumedActivity != null
2451                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2452                            Binder.getCallingUid()) {
2453                mAppSwitchesAllowedTime = 0;
2454            }
2455        }
2456        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2457                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2458        return ret;
2459    }
2460
2461    public boolean startNextMatchingActivity(IBinder callingActivity,
2462            Intent intent, Bundle options) {
2463        // Refuse possible leaked file descriptors
2464        if (intent != null && intent.hasFileDescriptors() == true) {
2465            throw new IllegalArgumentException("File descriptors passed in Intent");
2466        }
2467
2468        synchronized (this) {
2469            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2470            if (r == null) {
2471                ActivityOptions.abort(options);
2472                return false;
2473            }
2474            if (r.app == null || r.app.thread == null) {
2475                // The caller is not running...  d'oh!
2476                ActivityOptions.abort(options);
2477                return false;
2478            }
2479            intent = new Intent(intent);
2480            // The caller is not allowed to change the data.
2481            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2482            // And we are resetting to find the next component...
2483            intent.setComponent(null);
2484
2485            ActivityInfo aInfo = null;
2486            try {
2487                List<ResolveInfo> resolves =
2488                    AppGlobals.getPackageManager().queryIntentActivities(
2489                            intent, r.resolvedType,
2490                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2491                            UserHandle.getCallingUserId());
2492
2493                // Look for the original activity in the list...
2494                final int N = resolves != null ? resolves.size() : 0;
2495                for (int i=0; i<N; i++) {
2496                    ResolveInfo rInfo = resolves.get(i);
2497                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2498                            && rInfo.activityInfo.name.equals(r.info.name)) {
2499                        // We found the current one...  the next matching is
2500                        // after it.
2501                        i++;
2502                        if (i<N) {
2503                            aInfo = resolves.get(i).activityInfo;
2504                        }
2505                        break;
2506                    }
2507                }
2508            } catch (RemoteException e) {
2509            }
2510
2511            if (aInfo == null) {
2512                // Nobody who is next!
2513                ActivityOptions.abort(options);
2514                return false;
2515            }
2516
2517            intent.setComponent(new ComponentName(
2518                    aInfo.applicationInfo.packageName, aInfo.name));
2519            intent.setFlags(intent.getFlags()&~(
2520                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2521                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2522                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2523                    Intent.FLAG_ACTIVITY_NEW_TASK));
2524
2525            // Okay now we need to start the new activity, replacing the
2526            // currently running activity.  This is a little tricky because
2527            // we want to start the new one as if the current one is finished,
2528            // but not finish the current one first so that there is no flicker.
2529            // And thus...
2530            final boolean wasFinishing = r.finishing;
2531            r.finishing = true;
2532
2533            // Propagate reply information over to the new activity.
2534            final ActivityRecord resultTo = r.resultTo;
2535            final String resultWho = r.resultWho;
2536            final int requestCode = r.requestCode;
2537            r.resultTo = null;
2538            if (resultTo != null) {
2539                resultTo.removeResultsLocked(r, resultWho, requestCode);
2540            }
2541
2542            final long origId = Binder.clearCallingIdentity();
2543            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2544                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2545                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2546                    options, false, null);
2547            Binder.restoreCallingIdentity(origId);
2548
2549            r.finishing = wasFinishing;
2550            if (res != ActivityManager.START_SUCCESS) {
2551                return false;
2552            }
2553            return true;
2554        }
2555    }
2556
2557    final int startActivityInPackage(int uid,
2558            Intent intent, String resolvedType, IBinder resultTo,
2559            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2560
2561        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2562                false, true, "startActivityInPackage", null);
2563
2564        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2565                resultTo, resultWho, requestCode, startFlags,
2566                null, null, null, null, options, userId);
2567        return ret;
2568    }
2569
2570    public final int startActivities(IApplicationThread caller,
2571            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2572        enforceNotIsolatedCaller("startActivities");
2573        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2574                options, UserHandle.getCallingUserId());
2575        return ret;
2576    }
2577
2578    final int startActivitiesInPackage(int uid,
2579            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2580            Bundle options, int userId) {
2581
2582        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2583                false, true, "startActivityInPackage", null);
2584        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2585                options, userId);
2586        return ret;
2587    }
2588
2589    final void addRecentTaskLocked(TaskRecord task) {
2590        int N = mRecentTasks.size();
2591        // Quick case: check if the top-most recent task is the same.
2592        if (N > 0 && mRecentTasks.get(0) == task) {
2593            return;
2594        }
2595        // Remove any existing entries that are the same kind of task.
2596        for (int i=0; i<N; i++) {
2597            TaskRecord tr = mRecentTasks.get(i);
2598            if (task.userId == tr.userId
2599                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2600                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2601                mRecentTasks.remove(i);
2602                i--;
2603                N--;
2604                if (task.intent == null) {
2605                    // If the new recent task we are adding is not fully
2606                    // specified, then replace it with the existing recent task.
2607                    task = tr;
2608                }
2609            }
2610        }
2611        if (N >= MAX_RECENT_TASKS) {
2612            mRecentTasks.remove(N-1);
2613        }
2614        mRecentTasks.add(0, task);
2615    }
2616
2617    public void setRequestedOrientation(IBinder token,
2618            int requestedOrientation) {
2619        synchronized (this) {
2620            ActivityRecord r = mMainStack.isInStackLocked(token);
2621            if (r == null) {
2622                return;
2623            }
2624            final long origId = Binder.clearCallingIdentity();
2625            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2626            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2627                    mConfiguration,
2628                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2629            if (config != null) {
2630                r.frozenBeforeDestroy = true;
2631                if (!updateConfigurationLocked(config, r, false, false)) {
2632                    mMainStack.resumeTopActivityLocked(null);
2633                }
2634            }
2635            Binder.restoreCallingIdentity(origId);
2636        }
2637    }
2638
2639    public int getRequestedOrientation(IBinder token) {
2640        synchronized (this) {
2641            ActivityRecord r = mMainStack.isInStackLocked(token);
2642            if (r == null) {
2643                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2644            }
2645            return mWindowManager.getAppOrientation(r.appToken);
2646        }
2647    }
2648
2649    /**
2650     * This is the internal entry point for handling Activity.finish().
2651     *
2652     * @param token The Binder token referencing the Activity we want to finish.
2653     * @param resultCode Result code, if any, from this Activity.
2654     * @param resultData Result data (Intent), if any, from this Activity.
2655     *
2656     * @return Returns true if the activity successfully finished, or false if it is still running.
2657     */
2658    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2659        // Refuse possible leaked file descriptors
2660        if (resultData != null && resultData.hasFileDescriptors() == true) {
2661            throw new IllegalArgumentException("File descriptors passed in Intent");
2662        }
2663
2664        synchronized(this) {
2665            if (mController != null) {
2666                // Find the first activity that is not finishing.
2667                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2668                if (next != null) {
2669                    // ask watcher if this is allowed
2670                    boolean resumeOK = true;
2671                    try {
2672                        resumeOK = mController.activityResuming(next.packageName);
2673                    } catch (RemoteException e) {
2674                        mController = null;
2675                    }
2676
2677                    if (!resumeOK) {
2678                        return false;
2679                    }
2680                }
2681            }
2682            final long origId = Binder.clearCallingIdentity();
2683            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2684                    resultData, "app-request", true);
2685            Binder.restoreCallingIdentity(origId);
2686            return res;
2687        }
2688    }
2689
2690    public final void finishHeavyWeightApp() {
2691        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2692                != PackageManager.PERMISSION_GRANTED) {
2693            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2694                    + Binder.getCallingPid()
2695                    + ", uid=" + Binder.getCallingUid()
2696                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2697            Slog.w(TAG, msg);
2698            throw new SecurityException(msg);
2699        }
2700
2701        synchronized(this) {
2702            if (mHeavyWeightProcess == null) {
2703                return;
2704            }
2705
2706            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2707                    mHeavyWeightProcess.activities);
2708            for (int i=0; i<activities.size(); i++) {
2709                ActivityRecord r = activities.get(i);
2710                if (!r.finishing) {
2711                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2712                    if (index >= 0) {
2713                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2714                                null, "finish-heavy", true);
2715                    }
2716                }
2717            }
2718
2719            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2720                    mHeavyWeightProcess.userId, 0));
2721            mHeavyWeightProcess = null;
2722        }
2723    }
2724
2725    public void crashApplication(int uid, int initialPid, String packageName,
2726            String message) {
2727        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2728                != PackageManager.PERMISSION_GRANTED) {
2729            String msg = "Permission Denial: crashApplication() from pid="
2730                    + Binder.getCallingPid()
2731                    + ", uid=" + Binder.getCallingUid()
2732                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2733            Slog.w(TAG, msg);
2734            throw new SecurityException(msg);
2735        }
2736
2737        synchronized(this) {
2738            ProcessRecord proc = null;
2739
2740            // Figure out which process to kill.  We don't trust that initialPid
2741            // still has any relation to current pids, so must scan through the
2742            // list.
2743            synchronized (mPidsSelfLocked) {
2744                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2745                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2746                    if (p.uid != uid) {
2747                        continue;
2748                    }
2749                    if (p.pid == initialPid) {
2750                        proc = p;
2751                        break;
2752                    }
2753                    for (String str : p.pkgList) {
2754                        if (str.equals(packageName)) {
2755                            proc = p;
2756                        }
2757                    }
2758                }
2759            }
2760
2761            if (proc == null) {
2762                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2763                        + " initialPid=" + initialPid
2764                        + " packageName=" + packageName);
2765                return;
2766            }
2767
2768            if (proc.thread != null) {
2769                if (proc.pid == Process.myPid()) {
2770                    Log.w(TAG, "crashApplication: trying to crash self!");
2771                    return;
2772                }
2773                long ident = Binder.clearCallingIdentity();
2774                try {
2775                    proc.thread.scheduleCrash(message);
2776                } catch (RemoteException e) {
2777                }
2778                Binder.restoreCallingIdentity(ident);
2779            }
2780        }
2781    }
2782
2783    public final void finishSubActivity(IBinder token, String resultWho,
2784            int requestCode) {
2785        synchronized(this) {
2786            final long origId = Binder.clearCallingIdentity();
2787            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2788            Binder.restoreCallingIdentity(origId);
2789        }
2790    }
2791
2792    public boolean finishActivityAffinity(IBinder token) {
2793        synchronized(this) {
2794            final long origId = Binder.clearCallingIdentity();
2795            boolean res = mMainStack.finishActivityAffinityLocked(token);
2796            Binder.restoreCallingIdentity(origId);
2797            return res;
2798        }
2799    }
2800
2801    public boolean willActivityBeVisible(IBinder token) {
2802        synchronized(this) {
2803            int i;
2804            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2805                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2806                if (r.appToken == token) {
2807                    return true;
2808                }
2809                if (r.fullscreen && !r.finishing) {
2810                    return false;
2811                }
2812            }
2813            return true;
2814        }
2815    }
2816
2817    public void overridePendingTransition(IBinder token, String packageName,
2818            int enterAnim, int exitAnim) {
2819        synchronized(this) {
2820            ActivityRecord self = mMainStack.isInStackLocked(token);
2821            if (self == null) {
2822                return;
2823            }
2824
2825            final long origId = Binder.clearCallingIdentity();
2826
2827            if (self.state == ActivityState.RESUMED
2828                    || self.state == ActivityState.PAUSING) {
2829                mWindowManager.overridePendingAppTransition(packageName,
2830                        enterAnim, exitAnim, null);
2831            }
2832
2833            Binder.restoreCallingIdentity(origId);
2834        }
2835    }
2836
2837    /**
2838     * Main function for removing an existing process from the activity manager
2839     * as a result of that process going away.  Clears out all connections
2840     * to the process.
2841     */
2842    private final void handleAppDiedLocked(ProcessRecord app,
2843            boolean restarting, boolean allowRestart) {
2844        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2845        if (!restarting) {
2846            mLruProcesses.remove(app);
2847        }
2848
2849        if (mProfileProc == app) {
2850            clearProfilerLocked();
2851        }
2852
2853        // Just in case...
2854        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2855            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2856            mMainStack.mPausingActivity = null;
2857        }
2858        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2859            mMainStack.mLastPausedActivity = null;
2860        }
2861
2862        // Remove this application's activities from active lists.
2863        mMainStack.removeHistoryRecordsForAppLocked(app);
2864
2865        boolean atTop = true;
2866        boolean hasVisibleActivities = false;
2867
2868        // Clean out the history list.
2869        int i = mMainStack.mHistory.size();
2870        if (localLOGV) Slog.v(
2871            TAG, "Removing app " + app + " from history with " + i + " entries");
2872        while (i > 0) {
2873            i--;
2874            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2875            if (localLOGV) Slog.v(
2876                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2877            if (r.app == app) {
2878                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2879                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2880                        RuntimeException here = new RuntimeException("here");
2881                        here.fillInStackTrace();
2882                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2883                                + ": haveState=" + r.haveState
2884                                + " stateNotNeeded=" + r.stateNotNeeded
2885                                + " finishing=" + r.finishing
2886                                + " state=" + r.state, here);
2887                    }
2888                    if (!r.finishing) {
2889                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2890                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2891                                System.identityHashCode(r),
2892                                r.task.taskId, r.shortComponentName,
2893                                "proc died without state saved");
2894                    }
2895                    mMainStack.removeActivityFromHistoryLocked(r);
2896
2897                } else {
2898                    // We have the current state for this activity, so
2899                    // it can be restarted later when needed.
2900                    if (localLOGV) Slog.v(
2901                        TAG, "Keeping entry, setting app to null");
2902                    if (r.visible) {
2903                        hasVisibleActivities = true;
2904                    }
2905                    r.app = null;
2906                    r.nowVisible = false;
2907                    if (!r.haveState) {
2908                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2909                                "App died, clearing saved state of " + r);
2910                        r.icicle = null;
2911                    }
2912                }
2913
2914                r.stack.cleanUpActivityLocked(r, true, true);
2915            }
2916            atTop = false;
2917        }
2918
2919        app.activities.clear();
2920
2921        if (app.instrumentationClass != null) {
2922            Slog.w(TAG, "Crash of app " + app.processName
2923                  + " running instrumentation " + app.instrumentationClass);
2924            Bundle info = new Bundle();
2925            info.putString("shortMsg", "Process crashed.");
2926            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2927        }
2928
2929        if (!restarting) {
2930            if (!mMainStack.resumeTopActivityLocked(null)) {
2931                // If there was nothing to resume, and we are not already
2932                // restarting this process, but there is a visible activity that
2933                // is hosted by the process...  then make sure all visible
2934                // activities are running, taking care of restarting this
2935                // process.
2936                if (hasVisibleActivities) {
2937                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2938                }
2939            }
2940        }
2941    }
2942
2943    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2944        IBinder threadBinder = thread.asBinder();
2945        // Find the application record.
2946        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2947            ProcessRecord rec = mLruProcesses.get(i);
2948            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2949                return i;
2950            }
2951        }
2952        return -1;
2953    }
2954
2955    final ProcessRecord getRecordForAppLocked(
2956            IApplicationThread thread) {
2957        if (thread == null) {
2958            return null;
2959        }
2960
2961        int appIndex = getLRURecordIndexForAppLocked(thread);
2962        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2963    }
2964
2965    final void appDiedLocked(ProcessRecord app, int pid,
2966            IApplicationThread thread) {
2967
2968        mProcDeaths[0]++;
2969
2970        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2971        synchronized (stats) {
2972            stats.noteProcessDiedLocked(app.info.uid, pid);
2973        }
2974
2975        // Clean up already done if the process has been re-started.
2976        if (app.pid == pid && app.thread != null &&
2977                app.thread.asBinder() == thread.asBinder()) {
2978            if (!app.killedBackground) {
2979                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2980                        + ") has died.");
2981            }
2982            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2983            if (localLOGV) Slog.v(
2984                TAG, "Dying app: " + app + ", pid: " + pid
2985                + ", thread: " + thread.asBinder());
2986            boolean doLowMem = app.instrumentationClass == null;
2987            handleAppDiedLocked(app, false, true);
2988
2989            if (doLowMem) {
2990                // If there are no longer any background processes running,
2991                // and the app that died was not running instrumentation,
2992                // then tell everyone we are now low on memory.
2993                boolean haveBg = false;
2994                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2995                    ProcessRecord rec = mLruProcesses.get(i);
2996                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2997                        haveBg = true;
2998                        break;
2999                    }
3000                }
3001
3002                if (!haveBg) {
3003                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3004                    long now = SystemClock.uptimeMillis();
3005                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
3006                        ProcessRecord rec = mLruProcesses.get(i);
3007                        if (rec != app && rec.thread != null &&
3008                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3009                            // The low memory report is overriding any current
3010                            // state for a GC request.  Make sure to do
3011                            // heavy/important/visible/foreground processes first.
3012                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3013                                rec.lastRequestedGc = 0;
3014                            } else {
3015                                rec.lastRequestedGc = rec.lastLowMemory;
3016                            }
3017                            rec.reportLowMemory = true;
3018                            rec.lastLowMemory = now;
3019                            mProcessesToGc.remove(rec);
3020                            addProcessToGcListLocked(rec);
3021                        }
3022                    }
3023                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3024                    scheduleAppGcsLocked();
3025                }
3026            }
3027        } else if (app.pid != pid) {
3028            // A new process has already been started.
3029            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3030                    + ") has died and restarted (pid " + app.pid + ").");
3031            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3032        } else if (DEBUG_PROCESSES) {
3033            Slog.d(TAG, "Received spurious death notification for thread "
3034                    + thread.asBinder());
3035        }
3036    }
3037
3038    /**
3039     * If a stack trace dump file is configured, dump process stack traces.
3040     * @param clearTraces causes the dump file to be erased prior to the new
3041     *    traces being written, if true; when false, the new traces will be
3042     *    appended to any existing file content.
3043     * @param firstPids of dalvik VM processes to dump stack traces for first
3044     * @param lastPids of dalvik VM processes to dump stack traces for last
3045     * @param nativeProcs optional list of native process names to dump stack crawls
3046     * @return file containing stack traces, or null if no dump file is configured
3047     */
3048    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3049            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3050        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3051        if (tracesPath == null || tracesPath.length() == 0) {
3052            return null;
3053        }
3054
3055        File tracesFile = new File(tracesPath);
3056        try {
3057            File tracesDir = tracesFile.getParentFile();
3058            if (!tracesDir.exists()) {
3059                tracesFile.mkdirs();
3060                if (!SELinux.restorecon(tracesDir)) {
3061                    return null;
3062                }
3063            }
3064            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3065
3066            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3067            tracesFile.createNewFile();
3068            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3069        } catch (IOException e) {
3070            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3071            return null;
3072        }
3073
3074        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3075        return tracesFile;
3076    }
3077
3078    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3079            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3080        // Use a FileObserver to detect when traces finish writing.
3081        // The order of traces is considered important to maintain for legibility.
3082        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3083            public synchronized void onEvent(int event, String path) { notify(); }
3084        };
3085
3086        try {
3087            observer.startWatching();
3088
3089            // First collect all of the stacks of the most important pids.
3090            if (firstPids != null) {
3091                try {
3092                    int num = firstPids.size();
3093                    for (int i = 0; i < num; i++) {
3094                        synchronized (observer) {
3095                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3096                            observer.wait(200);  // Wait for write-close, give up after 200msec
3097                        }
3098                    }
3099                } catch (InterruptedException e) {
3100                    Log.wtf(TAG, e);
3101                }
3102            }
3103
3104            // Next measure CPU usage.
3105            if (processStats != null) {
3106                processStats.init();
3107                System.gc();
3108                processStats.update();
3109                try {
3110                    synchronized (processStats) {
3111                        processStats.wait(500); // measure over 1/2 second.
3112                    }
3113                } catch (InterruptedException e) {
3114                }
3115                processStats.update();
3116
3117                // We'll take the stack crawls of just the top apps using CPU.
3118                final int N = processStats.countWorkingStats();
3119                int numProcs = 0;
3120                for (int i=0; i<N && numProcs<5; i++) {
3121                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3122                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3123                        numProcs++;
3124                        try {
3125                            synchronized (observer) {
3126                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3127                                observer.wait(200);  // Wait for write-close, give up after 200msec
3128                            }
3129                        } catch (InterruptedException e) {
3130                            Log.wtf(TAG, e);
3131                        }
3132
3133                    }
3134                }
3135            }
3136
3137        } finally {
3138            observer.stopWatching();
3139        }
3140
3141        if (nativeProcs != null) {
3142            int[] pids = Process.getPidsForCommands(nativeProcs);
3143            if (pids != null) {
3144                for (int pid : pids) {
3145                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3146                }
3147            }
3148        }
3149    }
3150
3151    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3152        if (true || IS_USER_BUILD) {
3153            return;
3154        }
3155        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3156        if (tracesPath == null || tracesPath.length() == 0) {
3157            return;
3158        }
3159
3160        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3161        StrictMode.allowThreadDiskWrites();
3162        try {
3163            final File tracesFile = new File(tracesPath);
3164            final File tracesDir = tracesFile.getParentFile();
3165            final File tracesTmp = new File(tracesDir, "__tmp__");
3166            try {
3167                if (!tracesDir.exists()) {
3168                    tracesFile.mkdirs();
3169                    if (!SELinux.restorecon(tracesDir.getPath())) {
3170                        return;
3171                    }
3172                }
3173                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3174
3175                if (tracesFile.exists()) {
3176                    tracesTmp.delete();
3177                    tracesFile.renameTo(tracesTmp);
3178                }
3179                StringBuilder sb = new StringBuilder();
3180                Time tobj = new Time();
3181                tobj.set(System.currentTimeMillis());
3182                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3183                sb.append(": ");
3184                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3185                sb.append(" since ");
3186                sb.append(msg);
3187                FileOutputStream fos = new FileOutputStream(tracesFile);
3188                fos.write(sb.toString().getBytes());
3189                if (app == null) {
3190                    fos.write("\n*** No application process!".getBytes());
3191                }
3192                fos.close();
3193                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3194            } catch (IOException e) {
3195                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3196                return;
3197            }
3198
3199            if (app != null) {
3200                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3201                firstPids.add(app.pid);
3202                dumpStackTraces(tracesPath, firstPids, null, null, null);
3203            }
3204
3205            File lastTracesFile = null;
3206            File curTracesFile = null;
3207            for (int i=9; i>=0; i--) {
3208                String name = String.format("slow%02d.txt", i);
3209                curTracesFile = new File(tracesDir, name);
3210                if (curTracesFile.exists()) {
3211                    if (lastTracesFile != null) {
3212                        curTracesFile.renameTo(lastTracesFile);
3213                    } else {
3214                        curTracesFile.delete();
3215                    }
3216                }
3217                lastTracesFile = curTracesFile;
3218            }
3219            tracesFile.renameTo(curTracesFile);
3220            if (tracesTmp.exists()) {
3221                tracesTmp.renameTo(tracesFile);
3222            }
3223        } finally {
3224            StrictMode.setThreadPolicy(oldPolicy);
3225        }
3226    }
3227
3228    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3229            ActivityRecord parent, final String annotation) {
3230        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3231        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3232
3233        if (mController != null) {
3234            try {
3235                // 0 == continue, -1 = kill process immediately
3236                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3237                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3238            } catch (RemoteException e) {
3239                mController = null;
3240            }
3241        }
3242
3243        long anrTime = SystemClock.uptimeMillis();
3244        if (MONITOR_CPU_USAGE) {
3245            updateCpuStatsNow();
3246        }
3247
3248        synchronized (this) {
3249            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3250            if (mShuttingDown) {
3251                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3252                return;
3253            } else if (app.notResponding) {
3254                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3255                return;
3256            } else if (app.crashing) {
3257                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3258                return;
3259            }
3260
3261            // In case we come through here for the same app before completing
3262            // this one, mark as anring now so we will bail out.
3263            app.notResponding = true;
3264
3265            // Log the ANR to the event log.
3266            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3267                    annotation);
3268
3269            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3270            firstPids.add(app.pid);
3271
3272            int parentPid = app.pid;
3273            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3274            if (parentPid != app.pid) firstPids.add(parentPid);
3275
3276            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3277
3278            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3279                ProcessRecord r = mLruProcesses.get(i);
3280                if (r != null && r.thread != null) {
3281                    int pid = r.pid;
3282                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3283                        if (r.persistent) {
3284                            firstPids.add(pid);
3285                        } else {
3286                            lastPids.put(pid, Boolean.TRUE);
3287                        }
3288                    }
3289                }
3290            }
3291        }
3292
3293        // Log the ANR to the main log.
3294        StringBuilder info = new StringBuilder();
3295        info.setLength(0);
3296        info.append("ANR in ").append(app.processName);
3297        if (activity != null && activity.shortComponentName != null) {
3298            info.append(" (").append(activity.shortComponentName).append(")");
3299        }
3300        info.append("\n");
3301        if (annotation != null) {
3302            info.append("Reason: ").append(annotation).append("\n");
3303        }
3304        if (parent != null && parent != activity) {
3305            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3306        }
3307
3308        final ProcessStats processStats = new ProcessStats(true);
3309
3310        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3311
3312        String cpuInfo = null;
3313        if (MONITOR_CPU_USAGE) {
3314            updateCpuStatsNow();
3315            synchronized (mProcessStatsThread) {
3316                cpuInfo = mProcessStats.printCurrentState(anrTime);
3317            }
3318            info.append(processStats.printCurrentLoad());
3319            info.append(cpuInfo);
3320        }
3321
3322        info.append(processStats.printCurrentState(anrTime));
3323
3324        Slog.e(TAG, info.toString());
3325        if (tracesFile == null) {
3326            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3327            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3328        }
3329
3330        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3331                cpuInfo, tracesFile, null);
3332
3333        if (mController != null) {
3334            try {
3335                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3336                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3337                if (res != 0) {
3338                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3339                    return;
3340                }
3341            } catch (RemoteException e) {
3342                mController = null;
3343            }
3344        }
3345
3346        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3347        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3348                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3349
3350        synchronized (this) {
3351            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3352                Slog.w(TAG, "Killing " + app + ": background ANR");
3353                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3354                        app.processName, app.setAdj, "background ANR");
3355                Process.killProcessQuiet(app.pid);
3356                return;
3357            }
3358
3359            // Set the app's notResponding state, and look up the errorReportReceiver
3360            makeAppNotRespondingLocked(app,
3361                    activity != null ? activity.shortComponentName : null,
3362                    annotation != null ? "ANR " + annotation : "ANR",
3363                    info.toString());
3364
3365            // Bring up the infamous App Not Responding dialog
3366            Message msg = Message.obtain();
3367            HashMap map = new HashMap();
3368            msg.what = SHOW_NOT_RESPONDING_MSG;
3369            msg.obj = map;
3370            map.put("app", app);
3371            if (activity != null) {
3372                map.put("activity", activity);
3373            }
3374
3375            mHandler.sendMessage(msg);
3376        }
3377    }
3378
3379    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3380        if (!mLaunchWarningShown) {
3381            mLaunchWarningShown = true;
3382            mHandler.post(new Runnable() {
3383                @Override
3384                public void run() {
3385                    synchronized (ActivityManagerService.this) {
3386                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3387                        d.show();
3388                        mHandler.postDelayed(new Runnable() {
3389                            @Override
3390                            public void run() {
3391                                synchronized (ActivityManagerService.this) {
3392                                    d.dismiss();
3393                                    mLaunchWarningShown = false;
3394                                }
3395                            }
3396                        }, 4000);
3397                    }
3398                }
3399            });
3400        }
3401    }
3402
3403    public boolean clearApplicationUserData(final String packageName,
3404            final IPackageDataObserver observer, final int userId) {
3405        enforceNotIsolatedCaller("clearApplicationUserData");
3406        int uid = Binder.getCallingUid();
3407        int pid = Binder.getCallingPid();
3408        long callingId = Binder.clearCallingIdentity();
3409        try {
3410            IPackageManager pm = AppGlobals.getPackageManager();
3411            int pkgUid = -1;
3412            synchronized(this) {
3413                try {
3414                    pkgUid = pm.getPackageUid(packageName, userId);
3415                } catch (RemoteException e) {
3416                }
3417                if (pkgUid == -1) {
3418                    Slog.w(TAG, "Invalid packageName:" + packageName);
3419                    return false;
3420                }
3421                if (uid == pkgUid || checkComponentPermission(
3422                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3423                        pid, uid, -1, true)
3424                        == PackageManager.PERMISSION_GRANTED) {
3425                    forceStopPackageLocked(packageName, pkgUid);
3426                } else {
3427                    throw new SecurityException(pid+" does not have permission:"+
3428                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3429                                    "for process:"+packageName);
3430                }
3431            }
3432
3433            try {
3434                //clear application user data
3435                pm.clearApplicationUserData(packageName, observer, userId);
3436                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3437                        Uri.fromParts("package", packageName, null));
3438                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3439                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3440                        null, null, 0, null, null, null, false, false, userId);
3441            } catch (RemoteException e) {
3442            }
3443        } finally {
3444            Binder.restoreCallingIdentity(callingId);
3445        }
3446        return true;
3447    }
3448
3449    public void killBackgroundProcesses(final String packageName) {
3450        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3451                != PackageManager.PERMISSION_GRANTED &&
3452                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3453                        != PackageManager.PERMISSION_GRANTED) {
3454            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3455                    + Binder.getCallingPid()
3456                    + ", uid=" + Binder.getCallingUid()
3457                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3458            Slog.w(TAG, msg);
3459            throw new SecurityException(msg);
3460        }
3461
3462        int userId = UserHandle.getCallingUserId();
3463        long callingId = Binder.clearCallingIdentity();
3464        try {
3465            IPackageManager pm = AppGlobals.getPackageManager();
3466            int pkgUid = -1;
3467            synchronized(this) {
3468                try {
3469                    pkgUid = pm.getPackageUid(packageName, userId);
3470                } catch (RemoteException e) {
3471                }
3472                if (pkgUid == -1) {
3473                    Slog.w(TAG, "Invalid packageName: " + packageName);
3474                    return;
3475                }
3476                killPackageProcessesLocked(packageName, pkgUid, -1,
3477                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3478            }
3479        } finally {
3480            Binder.restoreCallingIdentity(callingId);
3481        }
3482    }
3483
3484    public void killAllBackgroundProcesses() {
3485        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3486                != PackageManager.PERMISSION_GRANTED) {
3487            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3488                    + Binder.getCallingPid()
3489                    + ", uid=" + Binder.getCallingUid()
3490                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3491            Slog.w(TAG, msg);
3492            throw new SecurityException(msg);
3493        }
3494
3495        long callingId = Binder.clearCallingIdentity();
3496        try {
3497            synchronized(this) {
3498                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3499                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3500                    final int NA = apps.size();
3501                    for (int ia=0; ia<NA; ia++) {
3502                        ProcessRecord app = apps.valueAt(ia);
3503                        if (app.persistent) {
3504                            // we don't kill persistent processes
3505                            continue;
3506                        }
3507                        if (app.removed) {
3508                            procs.add(app);
3509                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3510                            app.removed = true;
3511                            procs.add(app);
3512                        }
3513                    }
3514                }
3515
3516                int N = procs.size();
3517                for (int i=0; i<N; i++) {
3518                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3519                }
3520            }
3521        } finally {
3522            Binder.restoreCallingIdentity(callingId);
3523        }
3524    }
3525
3526    public void forceStopPackage(final String packageName) {
3527        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3528                != PackageManager.PERMISSION_GRANTED) {
3529            String msg = "Permission Denial: forceStopPackage() from pid="
3530                    + Binder.getCallingPid()
3531                    + ", uid=" + Binder.getCallingUid()
3532                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3533            Slog.w(TAG, msg);
3534            throw new SecurityException(msg);
3535        }
3536        final int userId = UserHandle.getCallingUserId();
3537        long callingId = Binder.clearCallingIdentity();
3538        try {
3539            IPackageManager pm = AppGlobals.getPackageManager();
3540            int pkgUid = -1;
3541            synchronized(this) {
3542                try {
3543                    pkgUid = pm.getPackageUid(packageName, userId);
3544                } catch (RemoteException e) {
3545                }
3546                if (pkgUid == -1) {
3547                    Slog.w(TAG, "Invalid packageName: " + packageName);
3548                    return;
3549                }
3550                forceStopPackageLocked(packageName, pkgUid);
3551                try {
3552                    pm.setPackageStoppedState(packageName, true, userId);
3553                } catch (RemoteException e) {
3554                } catch (IllegalArgumentException e) {
3555                    Slog.w(TAG, "Failed trying to unstop package "
3556                            + packageName + ": " + e);
3557                }
3558            }
3559        } finally {
3560            Binder.restoreCallingIdentity(callingId);
3561        }
3562    }
3563
3564    /*
3565     * The pkg name and app id have to be specified.
3566     */
3567    public void killApplicationWithAppId(String pkg, int appid) {
3568        if (pkg == null) {
3569            return;
3570        }
3571        // Make sure the uid is valid.
3572        if (appid < 0) {
3573            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
3574            return;
3575        }
3576        int callerUid = Binder.getCallingUid();
3577        // Only the system server can kill an application
3578        if (callerUid == Process.SYSTEM_UID) {
3579            // Post an aysnc message to kill the application
3580            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3581            msg.arg1 = appid;
3582            msg.arg2 = 0;
3583            msg.obj = pkg;
3584            mHandler.sendMessage(msg);
3585        } else {
3586            throw new SecurityException(callerUid + " cannot kill pkg: " +
3587                    pkg);
3588        }
3589    }
3590
3591    public void closeSystemDialogs(String reason) {
3592        enforceNotIsolatedCaller("closeSystemDialogs");
3593
3594        final int pid = Binder.getCallingPid();
3595        final int uid = Binder.getCallingUid();
3596        final long origId = Binder.clearCallingIdentity();
3597        try {
3598            synchronized (this) {
3599                // Only allow this from foreground processes, so that background
3600                // applications can't abuse it to prevent system UI from being shown.
3601                if (uid >= Process.FIRST_APPLICATION_UID) {
3602                    ProcessRecord proc;
3603                    synchronized (mPidsSelfLocked) {
3604                        proc = mPidsSelfLocked.get(pid);
3605                    }
3606                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
3607                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
3608                                + " from background process " + proc);
3609                        return;
3610                    }
3611                }
3612                closeSystemDialogsLocked(reason);
3613            }
3614        } finally {
3615            Binder.restoreCallingIdentity(origId);
3616        }
3617    }
3618
3619    void closeSystemDialogsLocked(String reason) {
3620        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3621        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3622        if (reason != null) {
3623            intent.putExtra("reason", reason);
3624        }
3625        mWindowManager.closeSystemDialogs(reason);
3626
3627        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3628            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3629            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3630                r.stack.finishActivityLocked(r, i,
3631                        Activity.RESULT_CANCELED, null, "close-sys", true);
3632            }
3633        }
3634
3635        broadcastIntentLocked(null, null, intent, null,
3636                null, 0, null, null, null, false, false, -1,
3637                Process.SYSTEM_UID, UserHandle.USER_ALL);
3638    }
3639
3640    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3641            throws RemoteException {
3642        enforceNotIsolatedCaller("getProcessMemoryInfo");
3643        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3644        for (int i=pids.length-1; i>=0; i--) {
3645            infos[i] = new Debug.MemoryInfo();
3646            Debug.getMemoryInfo(pids[i], infos[i]);
3647        }
3648        return infos;
3649    }
3650
3651    public long[] getProcessPss(int[] pids) throws RemoteException {
3652        enforceNotIsolatedCaller("getProcessPss");
3653        long[] pss = new long[pids.length];
3654        for (int i=pids.length-1; i>=0; i--) {
3655            pss[i] = Debug.getPss(pids[i]);
3656        }
3657        return pss;
3658    }
3659
3660    public void killApplicationProcess(String processName, int uid) {
3661        if (processName == null) {
3662            return;
3663        }
3664
3665        int callerUid = Binder.getCallingUid();
3666        // Only the system server can kill an application
3667        if (callerUid == Process.SYSTEM_UID) {
3668            synchronized (this) {
3669                ProcessRecord app = getProcessRecordLocked(processName, uid);
3670                if (app != null && app.thread != null) {
3671                    try {
3672                        app.thread.scheduleSuicide();
3673                    } catch (RemoteException e) {
3674                        // If the other end already died, then our work here is done.
3675                    }
3676                } else {
3677                    Slog.w(TAG, "Process/uid not found attempting kill of "
3678                            + processName + " / " + uid);
3679                }
3680            }
3681        } else {
3682            throw new SecurityException(callerUid + " cannot kill app process: " +
3683                    processName);
3684        }
3685    }
3686
3687    private void forceStopPackageLocked(final String packageName, int uid) {
3688        forceStopPackageLocked(packageName, uid, false, false, true, false,
3689                UserHandle.getUserId(uid));
3690        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3691                Uri.fromParts("package", packageName, null));
3692        if (!mProcessesReady) {
3693            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3694        }
3695        intent.putExtra(Intent.EXTRA_UID, uid);
3696        broadcastIntentLocked(null, null, intent,
3697                null, null, 0, null, null, null,
3698                false, false,
3699                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3700    }
3701
3702    private void forceStopUserLocked(int userId) {
3703        forceStopPackageLocked(null, -1, false, false, true, false, userId);
3704        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3705        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3706        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3707        broadcastIntentLocked(null, null, intent,
3708                null, null, 0, null, null, null,
3709                false, false,
3710                MY_PID, Process.SYSTEM_UID, userId);
3711    }
3712
3713    private final boolean killPackageProcessesLocked(String packageName, int appId,
3714            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3715            boolean doit, boolean evenPersistent, String reason) {
3716        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3717
3718        // Remove all processes this package may have touched: all with the
3719        // same UID (except for the system or root user), and all whose name
3720        // matches the package name.
3721        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3722        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3723            final int NA = apps.size();
3724            for (int ia=0; ia<NA; ia++) {
3725                ProcessRecord app = apps.valueAt(ia);
3726                if (app.persistent && !evenPersistent) {
3727                    // we don't kill persistent processes
3728                    continue;
3729                }
3730                if (app.removed) {
3731                    if (doit) {
3732                        procs.add(app);
3733                    }
3734                    continue;
3735                }
3736
3737                // Skip process if it doesn't meet our oom adj requirement.
3738                if (app.setAdj < minOomAdj) {
3739                    continue;
3740                }
3741
3742                // If no package is specified, we call all processes under the
3743                // give user id.
3744                if (packageName == null) {
3745                    if (app.userId != userId) {
3746                        continue;
3747                    }
3748                // Package has been specified, we want to hit all processes
3749                // that match it.  We need to qualify this by the processes
3750                // that are running under the specified app and user ID.
3751                } else {
3752                    if (UserHandle.getAppId(app.uid) != appId) {
3753                        continue;
3754                    }
3755                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
3756                        continue;
3757                    }
3758                    if (!app.pkgList.contains(packageName)) {
3759                        continue;
3760                    }
3761                }
3762
3763                // Process has passed all conditions, kill it!
3764                if (!doit) {
3765                    return true;
3766                }
3767                app.removed = true;
3768                procs.add(app);
3769            }
3770        }
3771
3772        int N = procs.size();
3773        for (int i=0; i<N; i++) {
3774            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3775        }
3776        return N > 0;
3777    }
3778
3779    private final boolean forceStopPackageLocked(String name, int appId,
3780            boolean callerWillRestart, boolean purgeCache, boolean doit,
3781            boolean evenPersistent, int userId) {
3782        int i;
3783        int N;
3784
3785        if (userId == UserHandle.USER_ALL && name == null) {
3786            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
3787        }
3788
3789        if (appId < 0 && name != null) {
3790            try {
3791                appId = UserHandle.getAppId(
3792                        AppGlobals.getPackageManager().getPackageUid(name, 0));
3793            } catch (RemoteException e) {
3794            }
3795        }
3796
3797        if (doit) {
3798            if (name != null) {
3799                Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
3800                        + " user=" + userId);
3801            } else {
3802                Slog.i(TAG, "Force stopping user " + userId);
3803            }
3804
3805            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3806            while (badApps.hasNext()) {
3807                SparseArray<Long> ba = badApps.next();
3808                for (i=ba.size()-1; i>=0; i--) {
3809                    boolean remove = false;
3810                    final int entUid = ba.keyAt(i);
3811                    if (name != null) {
3812                        if (userId == UserHandle.USER_ALL) {
3813                            if (UserHandle.getAppId(entUid) == appId) {
3814                                remove = true;
3815                            }
3816                        } else {
3817                            if (entUid == UserHandle.getUid(userId, appId)) {
3818                                remove = true;
3819                            }
3820                        }
3821                    } else if (UserHandle.getUserId(entUid) == userId) {
3822                        remove = true;
3823                    }
3824                    if (remove) {
3825                        ba.removeAt(i);
3826                    }
3827                }
3828                if (ba.size() == 0) {
3829                    badApps.remove();
3830                }
3831            }
3832        }
3833
3834        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
3835                -100, callerWillRestart, false, doit, evenPersistent,
3836                name == null ? ("force stop user " + userId) : ("force stop " + name));
3837
3838        TaskRecord lastTask = null;
3839        for (i=0; i<mMainStack.mHistory.size(); i++) {
3840            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3841            final boolean samePackage = r.packageName.equals(name)
3842                    || (name == null && r.userId == userId);
3843            if ((userId == UserHandle.USER_ALL || r.userId == userId)
3844                    && (samePackage || r.task == lastTask)
3845                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3846                if (!doit) {
3847                    if (r.finishing) {
3848                        // If this activity is just finishing, then it is not
3849                        // interesting as far as something to stop.
3850                        continue;
3851                    }
3852                    return true;
3853                }
3854                didSomething = true;
3855                Slog.i(TAG, "  Force finishing activity " + r);
3856                if (samePackage) {
3857                    if (r.app != null) {
3858                        r.app.removed = true;
3859                    }
3860                    r.app = null;
3861                }
3862                lastTask = r.task;
3863                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3864                        null, "force-stop", true)) {
3865                    i--;
3866                }
3867            }
3868        }
3869
3870        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3871            if (!doit) {
3872                return true;
3873            }
3874            didSomething = true;
3875        }
3876
3877        if (name == null) {
3878            // Remove all sticky broadcasts from this user.
3879            mStickyBroadcasts.remove(userId);
3880        }
3881
3882        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3883        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
3884                userId, providers)) {
3885            if (!doit) {
3886                return true;
3887            }
3888            didSomething = true;
3889        }
3890        N = providers.size();
3891        for (i=0; i<N; i++) {
3892            removeDyingProviderLocked(null, providers.get(i), true);
3893        }
3894
3895        if (mIntentSenderRecords.size() > 0) {
3896            Iterator<WeakReference<PendingIntentRecord>> it
3897                    = mIntentSenderRecords.values().iterator();
3898            while (it.hasNext()) {
3899                WeakReference<PendingIntentRecord> wpir = it.next();
3900                if (wpir == null) {
3901                    it.remove();
3902                    continue;
3903                }
3904                PendingIntentRecord pir = wpir.get();
3905                if (pir == null) {
3906                    it.remove();
3907                    continue;
3908                }
3909                if (name == null) {
3910                    // Stopping user, remove all objects for the user.
3911                    if (pir.key.userId != userId) {
3912                        // Not the same user, skip it.
3913                        continue;
3914                    }
3915                } else {
3916                    if (UserHandle.getAppId(pir.uid) != appId) {
3917                        // Different app id, skip it.
3918                        continue;
3919                    }
3920                    if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
3921                        // Different user, skip it.
3922                        continue;
3923                    }
3924                    if (!pir.key.packageName.equals(name)) {
3925                        // Different package, skip it.
3926                        continue;
3927                    }
3928                }
3929                if (!doit) {
3930                    return true;
3931                }
3932                didSomething = true;
3933                it.remove();
3934                pir.canceled = true;
3935                if (pir.key.activity != null) {
3936                    pir.key.activity.pendingResults.remove(pir.ref);
3937                }
3938            }
3939        }
3940
3941        if (doit) {
3942            if (purgeCache && name != null) {
3943                AttributeCache ac = AttributeCache.instance();
3944                if (ac != null) {
3945                    ac.removePackage(name);
3946                }
3947            }
3948            if (mBooted) {
3949                mMainStack.resumeTopActivityLocked(null);
3950                mMainStack.scheduleIdleLocked();
3951            }
3952        }
3953
3954        return didSomething;
3955    }
3956
3957    private final boolean removeProcessLocked(ProcessRecord app,
3958            boolean callerWillRestart, boolean allowRestart, String reason) {
3959        final String name = app.processName;
3960        final int uid = app.uid;
3961        if (DEBUG_PROCESSES) Slog.d(
3962            TAG, "Force removing proc " + app.toShortString() + " (" + name
3963            + "/" + uid + ")");
3964
3965        mProcessNames.remove(name, uid);
3966        mIsolatedProcesses.remove(app.uid);
3967        if (mHeavyWeightProcess == app) {
3968            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3969                    mHeavyWeightProcess.userId, 0));
3970            mHeavyWeightProcess = null;
3971        }
3972        boolean needRestart = false;
3973        if (app.pid > 0 && app.pid != MY_PID) {
3974            int pid = app.pid;
3975            synchronized (mPidsSelfLocked) {
3976                mPidsSelfLocked.remove(pid);
3977                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3978            }
3979            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3980            handleAppDiedLocked(app, true, allowRestart);
3981            mLruProcesses.remove(app);
3982            Process.killProcessQuiet(pid);
3983
3984            if (app.persistent && !app.isolated) {
3985                if (!callerWillRestart) {
3986                    addAppLocked(app.info, false);
3987                } else {
3988                    needRestart = true;
3989                }
3990            }
3991        } else {
3992            mRemovedProcesses.add(app);
3993        }
3994
3995        return needRestart;
3996    }
3997
3998    private final void processStartTimedOutLocked(ProcessRecord app) {
3999        final int pid = app.pid;
4000        boolean gone = false;
4001        synchronized (mPidsSelfLocked) {
4002            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4003            if (knownApp != null && knownApp.thread == null) {
4004                mPidsSelfLocked.remove(pid);
4005                gone = true;
4006            }
4007        }
4008
4009        if (gone) {
4010            Slog.w(TAG, "Process " + app + " failed to attach");
4011            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
4012                    app.processName);
4013            mProcessNames.remove(app.processName, app.uid);
4014            mIsolatedProcesses.remove(app.uid);
4015            if (mHeavyWeightProcess == app) {
4016                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4017                        mHeavyWeightProcess.userId, 0));
4018                mHeavyWeightProcess = null;
4019            }
4020            // Take care of any launching providers waiting for this process.
4021            checkAppInLaunchingProvidersLocked(app, true);
4022            // Take care of any services that are waiting for the process.
4023            mServices.processStartTimedOutLocked(app);
4024            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
4025                    app.processName, app.setAdj, "start timeout");
4026            Process.killProcessQuiet(pid);
4027            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4028                Slog.w(TAG, "Unattached app died before backup, skipping");
4029                try {
4030                    IBackupManager bm = IBackupManager.Stub.asInterface(
4031                            ServiceManager.getService(Context.BACKUP_SERVICE));
4032                    bm.agentDisconnected(app.info.packageName);
4033                } catch (RemoteException e) {
4034                    // Can't happen; the backup manager is local
4035                }
4036            }
4037            if (isPendingBroadcastProcessLocked(pid)) {
4038                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4039                skipPendingBroadcastLocked(pid);
4040            }
4041        } else {
4042            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4043        }
4044    }
4045
4046    private final boolean attachApplicationLocked(IApplicationThread thread,
4047            int pid) {
4048
4049        // Find the application record that is being attached...  either via
4050        // the pid if we are running in multiple processes, or just pull the
4051        // next app record if we are emulating process with anonymous threads.
4052        ProcessRecord app;
4053        if (pid != MY_PID && pid >= 0) {
4054            synchronized (mPidsSelfLocked) {
4055                app = mPidsSelfLocked.get(pid);
4056            }
4057        } else {
4058            app = null;
4059        }
4060
4061        if (app == null) {
4062            Slog.w(TAG, "No pending application record for pid " + pid
4063                    + " (IApplicationThread " + thread + "); dropping process");
4064            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4065            if (pid > 0 && pid != MY_PID) {
4066                Process.killProcessQuiet(pid);
4067            } else {
4068                try {
4069                    thread.scheduleExit();
4070                } catch (Exception e) {
4071                    // Ignore exceptions.
4072                }
4073            }
4074            return false;
4075        }
4076
4077        // If this application record is still attached to a previous
4078        // process, clean it up now.
4079        if (app.thread != null) {
4080            handleAppDiedLocked(app, true, true);
4081        }
4082
4083        // Tell the process all about itself.
4084
4085        if (localLOGV) Slog.v(
4086                TAG, "Binding process pid " + pid + " to record " + app);
4087
4088        String processName = app.processName;
4089        try {
4090            AppDeathRecipient adr = new AppDeathRecipient(
4091                    app, pid, thread);
4092            thread.asBinder().linkToDeath(adr, 0);
4093            app.deathRecipient = adr;
4094        } catch (RemoteException e) {
4095            app.resetPackageList();
4096            startProcessLocked(app, "link fail", processName);
4097            return false;
4098        }
4099
4100        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
4101
4102        app.thread = thread;
4103        app.curAdj = app.setAdj = -100;
4104        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4105        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4106        app.forcingToForeground = null;
4107        app.foregroundServices = false;
4108        app.hasShownUi = false;
4109        app.debugging = false;
4110
4111        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4112
4113        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4114        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4115
4116        if (!normalMode) {
4117            Slog.i(TAG, "Launching preboot mode app: " + app);
4118        }
4119
4120        if (localLOGV) Slog.v(
4121            TAG, "New app record " + app
4122            + " thread=" + thread.asBinder() + " pid=" + pid);
4123        try {
4124            int testMode = IApplicationThread.DEBUG_OFF;
4125            if (mDebugApp != null && mDebugApp.equals(processName)) {
4126                testMode = mWaitForDebugger
4127                    ? IApplicationThread.DEBUG_WAIT
4128                    : IApplicationThread.DEBUG_ON;
4129                app.debugging = true;
4130                if (mDebugTransient) {
4131                    mDebugApp = mOrigDebugApp;
4132                    mWaitForDebugger = mOrigWaitForDebugger;
4133                }
4134            }
4135            String profileFile = app.instrumentationProfileFile;
4136            ParcelFileDescriptor profileFd = null;
4137            boolean profileAutoStop = false;
4138            if (mProfileApp != null && mProfileApp.equals(processName)) {
4139                mProfileProc = app;
4140                profileFile = mProfileFile;
4141                profileFd = mProfileFd;
4142                profileAutoStop = mAutoStopProfiler;
4143            }
4144            boolean enableOpenGlTrace = false;
4145            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4146                enableOpenGlTrace = true;
4147                mOpenGlTraceApp = null;
4148            }
4149
4150            // If the app is being launched for restore or full backup, set it up specially
4151            boolean isRestrictedBackupMode = false;
4152            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4153                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4154                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4155                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4156            }
4157
4158            ensurePackageDexOpt(app.instrumentationInfo != null
4159                    ? app.instrumentationInfo.packageName
4160                    : app.info.packageName);
4161            if (app.instrumentationClass != null) {
4162                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4163            }
4164            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4165                    + processName + " with config " + mConfiguration);
4166            ApplicationInfo appInfo = app.instrumentationInfo != null
4167                    ? app.instrumentationInfo : app.info;
4168            app.compat = compatibilityInfoForPackageLocked(appInfo);
4169            if (profileFd != null) {
4170                profileFd = profileFd.dup();
4171            }
4172            thread.bindApplication(processName, appInfo, providers,
4173                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4174                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4175                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4176                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4177                    mCoreSettingsObserver.getCoreSettingsLocked());
4178            updateLruProcessLocked(app, false, true);
4179            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4180        } catch (Exception e) {
4181            // todo: Yikes!  What should we do?  For now we will try to
4182            // start another process, but that could easily get us in
4183            // an infinite loop of restarting processes...
4184            Slog.w(TAG, "Exception thrown during bind!", e);
4185
4186            app.resetPackageList();
4187            app.unlinkDeathRecipient();
4188            startProcessLocked(app, "bind fail", processName);
4189            return false;
4190        }
4191
4192        // Remove this record from the list of starting applications.
4193        mPersistentStartingProcesses.remove(app);
4194        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4195                "Attach application locked removing on hold: " + app);
4196        mProcessesOnHold.remove(app);
4197
4198        boolean badApp = false;
4199        boolean didSomething = false;
4200
4201        // See if the top visible activity is waiting to run in this process...
4202        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4203        if (hr != null && normalMode) {
4204            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4205                    && processName.equals(hr.processName)) {
4206                try {
4207                    if (mHeadless) {
4208                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4209                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4210                        didSomething = true;
4211                    }
4212                } catch (Exception e) {
4213                    Slog.w(TAG, "Exception in new application when starting activity "
4214                          + hr.intent.getComponent().flattenToShortString(), e);
4215                    badApp = true;
4216                }
4217            } else {
4218                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4219            }
4220        }
4221
4222        // Find any services that should be running in this process...
4223        if (!badApp) {
4224            try {
4225                didSomething |= mServices.attachApplicationLocked(app, processName);
4226            } catch (Exception e) {
4227                badApp = true;
4228            }
4229        }
4230
4231        // Check if a next-broadcast receiver is in this process...
4232        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4233            try {
4234                didSomething = sendPendingBroadcastsLocked(app);
4235            } catch (Exception e) {
4236                // If the app died trying to launch the receiver we declare it 'bad'
4237                badApp = true;
4238            }
4239        }
4240
4241        // Check whether the next backup agent is in this process...
4242        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4243            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4244            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4245            try {
4246                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4247                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4248                        mBackupTarget.backupMode);
4249            } catch (Exception e) {
4250                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4251                e.printStackTrace();
4252            }
4253        }
4254
4255        if (badApp) {
4256            // todo: Also need to kill application to deal with all
4257            // kinds of exceptions.
4258            handleAppDiedLocked(app, false, true);
4259            return false;
4260        }
4261
4262        if (!didSomething) {
4263            updateOomAdjLocked();
4264        }
4265
4266        return true;
4267    }
4268
4269    public final void attachApplication(IApplicationThread thread) {
4270        synchronized (this) {
4271            int callingPid = Binder.getCallingPid();
4272            final long origId = Binder.clearCallingIdentity();
4273            attachApplicationLocked(thread, callingPid);
4274            Binder.restoreCallingIdentity(origId);
4275        }
4276    }
4277
4278    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4279        final long origId = Binder.clearCallingIdentity();
4280        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4281        if (stopProfiling) {
4282            synchronized (this) {
4283                if (mProfileProc == r.app) {
4284                    if (mProfileFd != null) {
4285                        try {
4286                            mProfileFd.close();
4287                        } catch (IOException e) {
4288                        }
4289                        clearProfilerLocked();
4290                    }
4291                }
4292            }
4293        }
4294        Binder.restoreCallingIdentity(origId);
4295    }
4296
4297    void enableScreenAfterBoot() {
4298        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4299                SystemClock.uptimeMillis());
4300        mWindowManager.enableScreenAfterBoot();
4301
4302        synchronized (this) {
4303            updateEventDispatchingLocked();
4304        }
4305    }
4306
4307    public void showBootMessage(final CharSequence msg, final boolean always) {
4308        enforceNotIsolatedCaller("showBootMessage");
4309        mWindowManager.showBootMessage(msg, always);
4310    }
4311
4312    public void dismissKeyguardOnNextActivity() {
4313        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4314        final long token = Binder.clearCallingIdentity();
4315        try {
4316            synchronized (this) {
4317                if (mLockScreenShown) {
4318                    mLockScreenShown = false;
4319                    comeOutOfSleepIfNeededLocked();
4320                }
4321                mMainStack.dismissKeyguardOnNextActivityLocked();
4322            }
4323        } finally {
4324            Binder.restoreCallingIdentity(token);
4325        }
4326    }
4327
4328    final void finishBooting() {
4329        IntentFilter pkgFilter = new IntentFilter();
4330        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4331        pkgFilter.addDataScheme("package");
4332        mContext.registerReceiver(new BroadcastReceiver() {
4333            @Override
4334            public void onReceive(Context context, Intent intent) {
4335                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4336                if (pkgs != null) {
4337                    for (String pkg : pkgs) {
4338                        synchronized (ActivityManagerService.this) {
4339                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4340                                setResultCode(Activity.RESULT_OK);
4341                                return;
4342                            }
4343                        }
4344                    }
4345                }
4346            }
4347        }, pkgFilter);
4348
4349        synchronized (this) {
4350            // Ensure that any processes we had put on hold are now started
4351            // up.
4352            final int NP = mProcessesOnHold.size();
4353            if (NP > 0) {
4354                ArrayList<ProcessRecord> procs =
4355                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4356                for (int ip=0; ip<NP; ip++) {
4357                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4358                            + procs.get(ip));
4359                    startProcessLocked(procs.get(ip), "on-hold", null);
4360                }
4361            }
4362
4363            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4364                // Start looking for apps that are abusing wake locks.
4365                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4366                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4367                // Tell anyone interested that we are done booting!
4368                SystemProperties.set("sys.boot_completed", "1");
4369                SystemProperties.set("dev.bootcomplete", "1");
4370                for (int i=0; i<mStartedUsers.size(); i++) {
4371                    UserStartedState uss = mStartedUsers.valueAt(i);
4372                    if (uss.mState == UserStartedState.STATE_BOOTING) {
4373                        uss.mState = UserStartedState.STATE_RUNNING;
4374                        final int userId = mStartedUsers.keyAt(i);
4375                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4376                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4377                        broadcastIntentLocked(null, null, intent,
4378                                null, null, 0, null, null,
4379                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4380                                false, false, MY_PID, Process.SYSTEM_UID, userId);
4381                    }
4382                }
4383            }
4384        }
4385    }
4386
4387    final void ensureBootCompleted() {
4388        boolean booting;
4389        boolean enableScreen;
4390        synchronized (this) {
4391            booting = mBooting;
4392            mBooting = false;
4393            enableScreen = !mBooted;
4394            mBooted = true;
4395        }
4396
4397        if (booting) {
4398            finishBooting();
4399        }
4400
4401        if (enableScreen) {
4402            enableScreenAfterBoot();
4403        }
4404    }
4405
4406    public final void activityPaused(IBinder token) {
4407        final long origId = Binder.clearCallingIdentity();
4408        mMainStack.activityPaused(token, false);
4409        Binder.restoreCallingIdentity(origId);
4410    }
4411
4412    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4413            CharSequence description) {
4414        if (localLOGV) Slog.v(
4415            TAG, "Activity stopped: token=" + token);
4416
4417        // Refuse possible leaked file descriptors
4418        if (icicle != null && icicle.hasFileDescriptors()) {
4419            throw new IllegalArgumentException("File descriptors passed in Bundle");
4420        }
4421
4422        ActivityRecord r = null;
4423
4424        final long origId = Binder.clearCallingIdentity();
4425
4426        synchronized (this) {
4427            r = mMainStack.isInStackLocked(token);
4428            if (r != null) {
4429                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4430            }
4431        }
4432
4433        if (r != null) {
4434            sendPendingThumbnail(r, null, null, null, false);
4435        }
4436
4437        trimApplications();
4438
4439        Binder.restoreCallingIdentity(origId);
4440    }
4441
4442    public final void activityDestroyed(IBinder token) {
4443        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4444        mMainStack.activityDestroyed(token);
4445    }
4446
4447    public String getCallingPackage(IBinder token) {
4448        synchronized (this) {
4449            ActivityRecord r = getCallingRecordLocked(token);
4450            return r != null && r.app != null ? r.info.packageName : null;
4451        }
4452    }
4453
4454    public ComponentName getCallingActivity(IBinder token) {
4455        synchronized (this) {
4456            ActivityRecord r = getCallingRecordLocked(token);
4457            return r != null ? r.intent.getComponent() : null;
4458        }
4459    }
4460
4461    private ActivityRecord getCallingRecordLocked(IBinder token) {
4462        ActivityRecord r = mMainStack.isInStackLocked(token);
4463        if (r == null) {
4464            return null;
4465        }
4466        return r.resultTo;
4467    }
4468
4469    public ComponentName getActivityClassForToken(IBinder token) {
4470        synchronized(this) {
4471            ActivityRecord r = mMainStack.isInStackLocked(token);
4472            if (r == null) {
4473                return null;
4474            }
4475            return r.intent.getComponent();
4476        }
4477    }
4478
4479    public String getPackageForToken(IBinder token) {
4480        synchronized(this) {
4481            ActivityRecord r = mMainStack.isInStackLocked(token);
4482            if (r == null) {
4483                return null;
4484            }
4485            return r.packageName;
4486        }
4487    }
4488
4489    public IIntentSender getIntentSender(int type,
4490            String packageName, IBinder token, String resultWho,
4491            int requestCode, Intent[] intents, String[] resolvedTypes,
4492            int flags, Bundle options, int userId) {
4493        enforceNotIsolatedCaller("getIntentSender");
4494        // Refuse possible leaked file descriptors
4495        if (intents != null) {
4496            if (intents.length < 1) {
4497                throw new IllegalArgumentException("Intents array length must be >= 1");
4498            }
4499            for (int i=0; i<intents.length; i++) {
4500                Intent intent = intents[i];
4501                if (intent != null) {
4502                    if (intent.hasFileDescriptors()) {
4503                        throw new IllegalArgumentException("File descriptors passed in Intent");
4504                    }
4505                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4506                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4507                        throw new IllegalArgumentException(
4508                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4509                    }
4510                    intents[i] = new Intent(intent);
4511                }
4512            }
4513            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4514                throw new IllegalArgumentException(
4515                        "Intent array length does not match resolvedTypes length");
4516            }
4517        }
4518        if (options != null) {
4519            if (options.hasFileDescriptors()) {
4520                throw new IllegalArgumentException("File descriptors passed in options");
4521            }
4522        }
4523
4524        synchronized(this) {
4525            int callingUid = Binder.getCallingUid();
4526            userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId,
4527                    false, true, "getIntentSender", null);
4528            try {
4529                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4530                    int uid = AppGlobals.getPackageManager()
4531                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4532                    if (!UserHandle.isSameApp(callingUid, uid)) {
4533                        String msg = "Permission Denial: getIntentSender() from pid="
4534                            + Binder.getCallingPid()
4535                            + ", uid=" + Binder.getCallingUid()
4536                            + ", (need uid=" + uid + ")"
4537                            + " is not allowed to send as package " + packageName;
4538                        Slog.w(TAG, msg);
4539                        throw new SecurityException(msg);
4540                    }
4541                }
4542
4543                return getIntentSenderLocked(type, packageName, callingUid, userId,
4544                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4545
4546            } catch (RemoteException e) {
4547                throw new SecurityException(e);
4548            }
4549        }
4550    }
4551
4552    IIntentSender getIntentSenderLocked(int type, String packageName,
4553            int callingUid, int userId, IBinder token, String resultWho,
4554            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4555            Bundle options) {
4556        if (DEBUG_MU)
4557            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4558        ActivityRecord activity = null;
4559        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4560            activity = mMainStack.isInStackLocked(token);
4561            if (activity == null) {
4562                return null;
4563            }
4564            if (activity.finishing) {
4565                return null;
4566            }
4567        }
4568
4569        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4570        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4571        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4572        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4573                |PendingIntent.FLAG_UPDATE_CURRENT);
4574
4575        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4576                type, packageName, activity, resultWho,
4577                requestCode, intents, resolvedTypes, flags, options, userId);
4578        WeakReference<PendingIntentRecord> ref;
4579        ref = mIntentSenderRecords.get(key);
4580        PendingIntentRecord rec = ref != null ? ref.get() : null;
4581        if (rec != null) {
4582            if (!cancelCurrent) {
4583                if (updateCurrent) {
4584                    if (rec.key.requestIntent != null) {
4585                        rec.key.requestIntent.replaceExtras(intents != null ?
4586                                intents[intents.length - 1] : null);
4587                    }
4588                    if (intents != null) {
4589                        intents[intents.length-1] = rec.key.requestIntent;
4590                        rec.key.allIntents = intents;
4591                        rec.key.allResolvedTypes = resolvedTypes;
4592                    } else {
4593                        rec.key.allIntents = null;
4594                        rec.key.allResolvedTypes = null;
4595                    }
4596                }
4597                return rec;
4598            }
4599            rec.canceled = true;
4600            mIntentSenderRecords.remove(key);
4601        }
4602        if (noCreate) {
4603            return rec;
4604        }
4605        rec = new PendingIntentRecord(this, key, callingUid);
4606        mIntentSenderRecords.put(key, rec.ref);
4607        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4608            if (activity.pendingResults == null) {
4609                activity.pendingResults
4610                        = new HashSet<WeakReference<PendingIntentRecord>>();
4611            }
4612            activity.pendingResults.add(rec.ref);
4613        }
4614        return rec;
4615    }
4616
4617    public void cancelIntentSender(IIntentSender sender) {
4618        if (!(sender instanceof PendingIntentRecord)) {
4619            return;
4620        }
4621        synchronized(this) {
4622            PendingIntentRecord rec = (PendingIntentRecord)sender;
4623            try {
4624                int uid = AppGlobals.getPackageManager()
4625                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4626                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4627                    String msg = "Permission Denial: cancelIntentSender() from pid="
4628                        + Binder.getCallingPid()
4629                        + ", uid=" + Binder.getCallingUid()
4630                        + " is not allowed to cancel packges "
4631                        + rec.key.packageName;
4632                    Slog.w(TAG, msg);
4633                    throw new SecurityException(msg);
4634                }
4635            } catch (RemoteException e) {
4636                throw new SecurityException(e);
4637            }
4638            cancelIntentSenderLocked(rec, true);
4639        }
4640    }
4641
4642    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4643        rec.canceled = true;
4644        mIntentSenderRecords.remove(rec.key);
4645        if (cleanActivity && rec.key.activity != null) {
4646            rec.key.activity.pendingResults.remove(rec.ref);
4647        }
4648    }
4649
4650    public String getPackageForIntentSender(IIntentSender pendingResult) {
4651        if (!(pendingResult instanceof PendingIntentRecord)) {
4652            return null;
4653        }
4654        try {
4655            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4656            return res.key.packageName;
4657        } catch (ClassCastException e) {
4658        }
4659        return null;
4660    }
4661
4662    public int getUidForIntentSender(IIntentSender sender) {
4663        if (sender instanceof PendingIntentRecord) {
4664            try {
4665                PendingIntentRecord res = (PendingIntentRecord)sender;
4666                return res.uid;
4667            } catch (ClassCastException e) {
4668            }
4669        }
4670        return -1;
4671    }
4672
4673    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4674        if (!(pendingResult instanceof PendingIntentRecord)) {
4675            return false;
4676        }
4677        try {
4678            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4679            if (res.key.allIntents == null) {
4680                return false;
4681            }
4682            for (int i=0; i<res.key.allIntents.length; i++) {
4683                Intent intent = res.key.allIntents[i];
4684                if (intent.getPackage() != null && intent.getComponent() != null) {
4685                    return false;
4686                }
4687            }
4688            return true;
4689        } catch (ClassCastException e) {
4690        }
4691        return false;
4692    }
4693
4694    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4695        if (!(pendingResult instanceof PendingIntentRecord)) {
4696            return false;
4697        }
4698        try {
4699            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4700            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4701                return true;
4702            }
4703            return false;
4704        } catch (ClassCastException e) {
4705        }
4706        return false;
4707    }
4708
4709    public void setProcessLimit(int max) {
4710        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4711                "setProcessLimit()");
4712        synchronized (this) {
4713            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4714            mProcessLimitOverride = max;
4715        }
4716        trimApplications();
4717    }
4718
4719    public int getProcessLimit() {
4720        synchronized (this) {
4721            return mProcessLimitOverride;
4722        }
4723    }
4724
4725    void foregroundTokenDied(ForegroundToken token) {
4726        synchronized (ActivityManagerService.this) {
4727            synchronized (mPidsSelfLocked) {
4728                ForegroundToken cur
4729                    = mForegroundProcesses.get(token.pid);
4730                if (cur != token) {
4731                    return;
4732                }
4733                mForegroundProcesses.remove(token.pid);
4734                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4735                if (pr == null) {
4736                    return;
4737                }
4738                pr.forcingToForeground = null;
4739                pr.foregroundServices = false;
4740            }
4741            updateOomAdjLocked();
4742        }
4743    }
4744
4745    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4746        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4747                "setProcessForeground()");
4748        synchronized(this) {
4749            boolean changed = false;
4750
4751            synchronized (mPidsSelfLocked) {
4752                ProcessRecord pr = mPidsSelfLocked.get(pid);
4753                if (pr == null && isForeground) {
4754                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4755                    return;
4756                }
4757                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4758                if (oldToken != null) {
4759                    oldToken.token.unlinkToDeath(oldToken, 0);
4760                    mForegroundProcesses.remove(pid);
4761                    if (pr != null) {
4762                        pr.forcingToForeground = null;
4763                    }
4764                    changed = true;
4765                }
4766                if (isForeground && token != null) {
4767                    ForegroundToken newToken = new ForegroundToken() {
4768                        public void binderDied() {
4769                            foregroundTokenDied(this);
4770                        }
4771                    };
4772                    newToken.pid = pid;
4773                    newToken.token = token;
4774                    try {
4775                        token.linkToDeath(newToken, 0);
4776                        mForegroundProcesses.put(pid, newToken);
4777                        pr.forcingToForeground = token;
4778                        changed = true;
4779                    } catch (RemoteException e) {
4780                        // If the process died while doing this, we will later
4781                        // do the cleanup with the process death link.
4782                    }
4783                }
4784            }
4785
4786            if (changed) {
4787                updateOomAdjLocked();
4788            }
4789        }
4790    }
4791
4792    // =========================================================
4793    // PERMISSIONS
4794    // =========================================================
4795
4796    static class PermissionController extends IPermissionController.Stub {
4797        ActivityManagerService mActivityManagerService;
4798        PermissionController(ActivityManagerService activityManagerService) {
4799            mActivityManagerService = activityManagerService;
4800        }
4801
4802        public boolean checkPermission(String permission, int pid, int uid) {
4803            return mActivityManagerService.checkPermission(permission, pid,
4804                    uid) == PackageManager.PERMISSION_GRANTED;
4805        }
4806    }
4807
4808    /**
4809     * This can be called with or without the global lock held.
4810     */
4811    int checkComponentPermission(String permission, int pid, int uid,
4812            int owningUid, boolean exported) {
4813        // We might be performing an operation on behalf of an indirect binder
4814        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4815        // client identity accordingly before proceeding.
4816        Identity tlsIdentity = sCallerIdentity.get();
4817        if (tlsIdentity != null) {
4818            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4819                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4820            uid = tlsIdentity.uid;
4821            pid = tlsIdentity.pid;
4822        }
4823
4824        if (pid == MY_PID) {
4825            return PackageManager.PERMISSION_GRANTED;
4826        }
4827
4828        return ActivityManager.checkComponentPermission(permission, uid,
4829                owningUid, exported);
4830    }
4831
4832    /**
4833     * As the only public entry point for permissions checking, this method
4834     * can enforce the semantic that requesting a check on a null global
4835     * permission is automatically denied.  (Internally a null permission
4836     * string is used when calling {@link #checkComponentPermission} in cases
4837     * when only uid-based security is needed.)
4838     *
4839     * This can be called with or without the global lock held.
4840     */
4841    public int checkPermission(String permission, int pid, int uid) {
4842        if (permission == null) {
4843            return PackageManager.PERMISSION_DENIED;
4844        }
4845        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4846    }
4847
4848    /**
4849     * Binder IPC calls go through the public entry point.
4850     * This can be called with or without the global lock held.
4851     */
4852    int checkCallingPermission(String permission) {
4853        return checkPermission(permission,
4854                Binder.getCallingPid(),
4855                UserHandle.getAppId(Binder.getCallingUid()));
4856    }
4857
4858    /**
4859     * This can be called with or without the global lock held.
4860     */
4861    void enforceCallingPermission(String permission, String func) {
4862        if (checkCallingPermission(permission)
4863                == PackageManager.PERMISSION_GRANTED) {
4864            return;
4865        }
4866
4867        String msg = "Permission Denial: " + func + " from pid="
4868                + Binder.getCallingPid()
4869                + ", uid=" + Binder.getCallingUid()
4870                + " requires " + permission;
4871        Slog.w(TAG, msg);
4872        throw new SecurityException(msg);
4873    }
4874
4875    /**
4876     * Determine if UID is holding permissions required to access {@link Uri} in
4877     * the given {@link ProviderInfo}. Final permission checking is always done
4878     * in {@link ContentProvider}.
4879     */
4880    private final boolean checkHoldingPermissionsLocked(
4881            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4882        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4883                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4884
4885        if (pi.applicationInfo.uid == uid) {
4886            return true;
4887        } else if (!pi.exported) {
4888            return false;
4889        }
4890
4891        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4892        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4893        try {
4894            // check if target holds top-level <provider> permissions
4895            if (!readMet && pi.readPermission != null
4896                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4897                readMet = true;
4898            }
4899            if (!writeMet && pi.writePermission != null
4900                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4901                writeMet = true;
4902            }
4903
4904            // track if unprotected read/write is allowed; any denied
4905            // <path-permission> below removes this ability
4906            boolean allowDefaultRead = pi.readPermission == null;
4907            boolean allowDefaultWrite = pi.writePermission == null;
4908
4909            // check if target holds any <path-permission> that match uri
4910            final PathPermission[] pps = pi.pathPermissions;
4911            if (pps != null) {
4912                final String path = uri.getPath();
4913                int i = pps.length;
4914                while (i > 0 && (!readMet || !writeMet)) {
4915                    i--;
4916                    PathPermission pp = pps[i];
4917                    if (pp.match(path)) {
4918                        if (!readMet) {
4919                            final String pprperm = pp.getReadPermission();
4920                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4921                                    + pprperm + " for " + pp.getPath()
4922                                    + ": match=" + pp.match(path)
4923                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4924                            if (pprperm != null) {
4925                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4926                                    readMet = true;
4927                                } else {
4928                                    allowDefaultRead = false;
4929                                }
4930                            }
4931                        }
4932                        if (!writeMet) {
4933                            final String ppwperm = pp.getWritePermission();
4934                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4935                                    + ppwperm + " for " + pp.getPath()
4936                                    + ": match=" + pp.match(path)
4937                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4938                            if (ppwperm != null) {
4939                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4940                                    writeMet = true;
4941                                } else {
4942                                    allowDefaultWrite = false;
4943                                }
4944                            }
4945                        }
4946                    }
4947                }
4948            }
4949
4950            // grant unprotected <provider> read/write, if not blocked by
4951            // <path-permission> above
4952            if (allowDefaultRead) readMet = true;
4953            if (allowDefaultWrite) writeMet = true;
4954
4955        } catch (RemoteException e) {
4956            return false;
4957        }
4958
4959        return readMet && writeMet;
4960    }
4961
4962    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4963            int modeFlags) {
4964        // Root gets to do everything.
4965        if (uid == 0) {
4966            return true;
4967        }
4968        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4969        if (perms == null) return false;
4970        UriPermission perm = perms.get(uri);
4971        if (perm == null) return false;
4972        return (modeFlags&perm.modeFlags) == modeFlags;
4973    }
4974
4975    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4976        enforceNotIsolatedCaller("checkUriPermission");
4977
4978        // Another redirected-binder-call permissions check as in
4979        // {@link checkComponentPermission}.
4980        Identity tlsIdentity = sCallerIdentity.get();
4981        if (tlsIdentity != null) {
4982            uid = tlsIdentity.uid;
4983            pid = tlsIdentity.pid;
4984        }
4985
4986        uid = UserHandle.getAppId(uid);
4987        // Our own process gets to do everything.
4988        if (pid == MY_PID) {
4989            return PackageManager.PERMISSION_GRANTED;
4990        }
4991        synchronized(this) {
4992            return checkUriPermissionLocked(uri, uid, modeFlags)
4993                    ? PackageManager.PERMISSION_GRANTED
4994                    : PackageManager.PERMISSION_DENIED;
4995        }
4996    }
4997
4998    /**
4999     * Check if the targetPkg can be granted permission to access uri by
5000     * the callingUid using the given modeFlags.  Throws a security exception
5001     * if callingUid is not allowed to do this.  Returns the uid of the target
5002     * if the URI permission grant should be performed; returns -1 if it is not
5003     * needed (for example targetPkg already has permission to access the URI).
5004     * If you already know the uid of the target, you can supply it in
5005     * lastTargetUid else set that to -1.
5006     */
5007    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5008            Uri uri, int modeFlags, int lastTargetUid) {
5009        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5010                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5011        if (modeFlags == 0) {
5012            return -1;
5013        }
5014
5015        if (targetPkg != null) {
5016            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5017                    "Checking grant " + targetPkg + " permission to " + uri);
5018        }
5019
5020        final IPackageManager pm = AppGlobals.getPackageManager();
5021
5022        // If this is not a content: uri, we can't do anything with it.
5023        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5024            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5025                    "Can't grant URI permission for non-content URI: " + uri);
5026            return -1;
5027        }
5028
5029        String name = uri.getAuthority();
5030        ProviderInfo pi = null;
5031        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5032                UserHandle.getUserId(callingUid));
5033        if (cpr != null) {
5034            pi = cpr.info;
5035        } else {
5036            try {
5037                pi = pm.resolveContentProvider(name,
5038                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid));
5039            } catch (RemoteException ex) {
5040            }
5041        }
5042        if (pi == null) {
5043            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5044            return -1;
5045        }
5046
5047        int targetUid = lastTargetUid;
5048        if (targetUid < 0 && targetPkg != null) {
5049            try {
5050                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5051                if (targetUid < 0) {
5052                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5053                            "Can't grant URI permission no uid for: " + targetPkg);
5054                    return -1;
5055                }
5056            } catch (RemoteException ex) {
5057                return -1;
5058            }
5059        }
5060
5061        if (targetUid >= 0) {
5062            // First...  does the target actually need this permission?
5063            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5064                // No need to grant the target this permission.
5065                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5066                        "Target " + targetPkg + " already has full permission to " + uri);
5067                return -1;
5068            }
5069        } else {
5070            // First...  there is no target package, so can anyone access it?
5071            boolean allowed = pi.exported;
5072            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5073                if (pi.readPermission != null) {
5074                    allowed = false;
5075                }
5076            }
5077            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5078                if (pi.writePermission != null) {
5079                    allowed = false;
5080                }
5081            }
5082            if (allowed) {
5083                return -1;
5084            }
5085        }
5086
5087        // Second...  is the provider allowing granting of URI permissions?
5088        if (!pi.grantUriPermissions) {
5089            throw new SecurityException("Provider " + pi.packageName
5090                    + "/" + pi.name
5091                    + " does not allow granting of Uri permissions (uri "
5092                    + uri + ")");
5093        }
5094        if (pi.uriPermissionPatterns != null) {
5095            final int N = pi.uriPermissionPatterns.length;
5096            boolean allowed = false;
5097            for (int i=0; i<N; i++) {
5098                if (pi.uriPermissionPatterns[i] != null
5099                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5100                    allowed = true;
5101                    break;
5102                }
5103            }
5104            if (!allowed) {
5105                throw new SecurityException("Provider " + pi.packageName
5106                        + "/" + pi.name
5107                        + " does not allow granting of permission to path of Uri "
5108                        + uri);
5109            }
5110        }
5111
5112        // Third...  does the caller itself have permission to access
5113        // this uri?
5114        if (callingUid != Process.myUid()) {
5115            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5116                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5117                    throw new SecurityException("Uid " + callingUid
5118                            + " does not have permission to uri " + uri);
5119                }
5120            }
5121        }
5122
5123        return targetUid;
5124    }
5125
5126    public int checkGrantUriPermission(int callingUid, String targetPkg,
5127            Uri uri, int modeFlags) {
5128        enforceNotIsolatedCaller("checkGrantUriPermission");
5129        synchronized(this) {
5130            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5131        }
5132    }
5133
5134    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5135            Uri uri, int modeFlags, UriPermissionOwner owner) {
5136        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5137                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5138        if (modeFlags == 0) {
5139            return;
5140        }
5141
5142        // So here we are: the caller has the assumed permission
5143        // to the uri, and the target doesn't.  Let's now give this to
5144        // the target.
5145
5146        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5147                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5148
5149        HashMap<Uri, UriPermission> targetUris
5150                = mGrantedUriPermissions.get(targetUid);
5151        if (targetUris == null) {
5152            targetUris = new HashMap<Uri, UriPermission>();
5153            mGrantedUriPermissions.put(targetUid, targetUris);
5154        }
5155
5156        UriPermission perm = targetUris.get(uri);
5157        if (perm == null) {
5158            perm = new UriPermission(targetUid, uri);
5159            targetUris.put(uri, perm);
5160        }
5161
5162        perm.modeFlags |= modeFlags;
5163        if (owner == null) {
5164            perm.globalModeFlags |= modeFlags;
5165        } else {
5166            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5167                 perm.readOwners.add(owner);
5168                 owner.addReadPermission(perm);
5169            }
5170            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5171                 perm.writeOwners.add(owner);
5172                 owner.addWritePermission(perm);
5173            }
5174        }
5175    }
5176
5177    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5178            int modeFlags, UriPermissionOwner owner) {
5179        if (targetPkg == null) {
5180            throw new NullPointerException("targetPkg");
5181        }
5182
5183        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5184        if (targetUid < 0) {
5185            return;
5186        }
5187
5188        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5189    }
5190
5191    static class NeededUriGrants extends ArrayList<Uri> {
5192        final String targetPkg;
5193        final int targetUid;
5194        final int flags;
5195
5196        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5197            targetPkg = _targetPkg;
5198            targetUid = _targetUid;
5199            flags = _flags;
5200        }
5201    }
5202
5203    /**
5204     * Like checkGrantUriPermissionLocked, but takes an Intent.
5205     */
5206    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5207            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5208        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5209                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5210                + " clip=" + (intent != null ? intent.getClipData() : null)
5211                + " from " + intent + "; flags=0x"
5212                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5213
5214        if (targetPkg == null) {
5215            throw new NullPointerException("targetPkg");
5216        }
5217
5218        if (intent == null) {
5219            return null;
5220        }
5221        Uri data = intent.getData();
5222        ClipData clip = intent.getClipData();
5223        if (data == null && clip == null) {
5224            return null;
5225        }
5226        if (data != null) {
5227            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5228                mode, needed != null ? needed.targetUid : -1);
5229            if (target > 0) {
5230                if (needed == null) {
5231                    needed = new NeededUriGrants(targetPkg, target, mode);
5232                }
5233                needed.add(data);
5234            }
5235        }
5236        if (clip != null) {
5237            for (int i=0; i<clip.getItemCount(); i++) {
5238                Uri uri = clip.getItemAt(i).getUri();
5239                if (uri != null) {
5240                    int target = -1;
5241                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5242                            mode, needed != null ? needed.targetUid : -1);
5243                    if (target > 0) {
5244                        if (needed == null) {
5245                            needed = new NeededUriGrants(targetPkg, target, mode);
5246                        }
5247                        needed.add(uri);
5248                    }
5249                } else {
5250                    Intent clipIntent = clip.getItemAt(i).getIntent();
5251                    if (clipIntent != null) {
5252                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5253                                callingUid, targetPkg, clipIntent, mode, needed);
5254                        if (newNeeded != null) {
5255                            needed = newNeeded;
5256                        }
5257                    }
5258                }
5259            }
5260        }
5261
5262        return needed;
5263    }
5264
5265    /**
5266     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5267     */
5268    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5269            UriPermissionOwner owner) {
5270        if (needed != null) {
5271            for (int i=0; i<needed.size(); i++) {
5272                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5273                        needed.get(i), needed.flags, owner);
5274            }
5275        }
5276    }
5277
5278    void grantUriPermissionFromIntentLocked(int callingUid,
5279            String targetPkg, Intent intent, UriPermissionOwner owner) {
5280        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5281                intent, intent != null ? intent.getFlags() : 0, null);
5282        if (needed == null) {
5283            return;
5284        }
5285
5286        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5287    }
5288
5289    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5290            Uri uri, int modeFlags) {
5291        enforceNotIsolatedCaller("grantUriPermission");
5292        synchronized(this) {
5293            final ProcessRecord r = getRecordForAppLocked(caller);
5294            if (r == null) {
5295                throw new SecurityException("Unable to find app for caller "
5296                        + caller
5297                        + " when granting permission to uri " + uri);
5298            }
5299            if (targetPkg == null) {
5300                throw new IllegalArgumentException("null target");
5301            }
5302            if (uri == null) {
5303                throw new IllegalArgumentException("null uri");
5304            }
5305
5306            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5307                    null);
5308        }
5309    }
5310
5311    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5312        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5313                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5314            HashMap<Uri, UriPermission> perms
5315                    = mGrantedUriPermissions.get(perm.uid);
5316            if (perms != null) {
5317                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5318                        "Removing " + perm.uid + " permission to " + perm.uri);
5319                perms.remove(perm.uri);
5320                if (perms.size() == 0) {
5321                    mGrantedUriPermissions.remove(perm.uid);
5322                }
5323            }
5324        }
5325    }
5326
5327    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5328            int modeFlags) {
5329        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5330                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5331        if (modeFlags == 0) {
5332            return;
5333        }
5334
5335        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5336                "Revoking all granted permissions to " + uri);
5337
5338        final IPackageManager pm = AppGlobals.getPackageManager();
5339
5340        final String authority = uri.getAuthority();
5341        ProviderInfo pi = null;
5342        int userId = UserHandle.getUserId(callingUid);
5343        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5344        if (cpr != null) {
5345            pi = cpr.info;
5346        } else {
5347            try {
5348                pi = pm.resolveContentProvider(authority,
5349                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5350            } catch (RemoteException ex) {
5351            }
5352        }
5353        if (pi == null) {
5354            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5355            return;
5356        }
5357
5358        // Does the caller have this permission on the URI?
5359        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5360            // Right now, if you are not the original owner of the permission,
5361            // you are not allowed to revoke it.
5362            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5363                throw new SecurityException("Uid " + callingUid
5364                        + " does not have permission to uri " + uri);
5365            //}
5366        }
5367
5368        // Go through all of the permissions and remove any that match.
5369        final List<String> SEGMENTS = uri.getPathSegments();
5370        if (SEGMENTS != null) {
5371            final int NS = SEGMENTS.size();
5372            int N = mGrantedUriPermissions.size();
5373            for (int i=0; i<N; i++) {
5374                HashMap<Uri, UriPermission> perms
5375                        = mGrantedUriPermissions.valueAt(i);
5376                Iterator<UriPermission> it = perms.values().iterator();
5377            toploop:
5378                while (it.hasNext()) {
5379                    UriPermission perm = it.next();
5380                    Uri targetUri = perm.uri;
5381                    if (!authority.equals(targetUri.getAuthority())) {
5382                        continue;
5383                    }
5384                    List<String> targetSegments = targetUri.getPathSegments();
5385                    if (targetSegments == null) {
5386                        continue;
5387                    }
5388                    if (targetSegments.size() < NS) {
5389                        continue;
5390                    }
5391                    for (int j=0; j<NS; j++) {
5392                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5393                            continue toploop;
5394                        }
5395                    }
5396                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5397                            "Revoking " + perm.uid + " permission to " + perm.uri);
5398                    perm.clearModes(modeFlags);
5399                    if (perm.modeFlags == 0) {
5400                        it.remove();
5401                    }
5402                }
5403                if (perms.size() == 0) {
5404                    mGrantedUriPermissions.remove(
5405                            mGrantedUriPermissions.keyAt(i));
5406                    N--;
5407                    i--;
5408                }
5409            }
5410        }
5411    }
5412
5413    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5414            int modeFlags) {
5415        enforceNotIsolatedCaller("revokeUriPermission");
5416        synchronized(this) {
5417            final ProcessRecord r = getRecordForAppLocked(caller);
5418            if (r == null) {
5419                throw new SecurityException("Unable to find app for caller "
5420                        + caller
5421                        + " when revoking permission to uri " + uri);
5422            }
5423            if (uri == null) {
5424                Slog.w(TAG, "revokeUriPermission: null uri");
5425                return;
5426            }
5427
5428            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5429                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5430            if (modeFlags == 0) {
5431                return;
5432            }
5433
5434            final IPackageManager pm = AppGlobals.getPackageManager();
5435
5436            final String authority = uri.getAuthority();
5437            ProviderInfo pi = null;
5438            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5439            if (cpr != null) {
5440                pi = cpr.info;
5441            } else {
5442                try {
5443                    pi = pm.resolveContentProvider(authority,
5444                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5445                } catch (RemoteException ex) {
5446                }
5447            }
5448            if (pi == null) {
5449                Slog.w(TAG, "No content provider found for permission revoke: "
5450                        + uri.toSafeString());
5451                return;
5452            }
5453
5454            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5455        }
5456    }
5457
5458    @Override
5459    public IBinder newUriPermissionOwner(String name) {
5460        enforceNotIsolatedCaller("newUriPermissionOwner");
5461        synchronized(this) {
5462            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5463            return owner.getExternalTokenLocked();
5464        }
5465    }
5466
5467    @Override
5468    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5469            Uri uri, int modeFlags) {
5470        synchronized(this) {
5471            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5472            if (owner == null) {
5473                throw new IllegalArgumentException("Unknown owner: " + token);
5474            }
5475            if (fromUid != Binder.getCallingUid()) {
5476                if (Binder.getCallingUid() != Process.myUid()) {
5477                    // Only system code can grant URI permissions on behalf
5478                    // of other users.
5479                    throw new SecurityException("nice try");
5480                }
5481            }
5482            if (targetPkg == null) {
5483                throw new IllegalArgumentException("null target");
5484            }
5485            if (uri == null) {
5486                throw new IllegalArgumentException("null uri");
5487            }
5488
5489            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5490        }
5491    }
5492
5493    @Override
5494    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5495        synchronized(this) {
5496            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5497            if (owner == null) {
5498                throw new IllegalArgumentException("Unknown owner: " + token);
5499            }
5500
5501            if (uri == null) {
5502                owner.removeUriPermissionsLocked(mode);
5503            } else {
5504                owner.removeUriPermissionLocked(uri, mode);
5505            }
5506        }
5507    }
5508
5509    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5510        synchronized (this) {
5511            ProcessRecord app =
5512                who != null ? getRecordForAppLocked(who) : null;
5513            if (app == null) return;
5514
5515            Message msg = Message.obtain();
5516            msg.what = WAIT_FOR_DEBUGGER_MSG;
5517            msg.obj = app;
5518            msg.arg1 = waiting ? 1 : 0;
5519            mHandler.sendMessage(msg);
5520        }
5521    }
5522
5523    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5524        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5525        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5526        outInfo.availMem = Process.getFreeMemory();
5527        outInfo.totalMem = Process.getTotalMemory();
5528        outInfo.threshold = homeAppMem;
5529        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5530        outInfo.hiddenAppThreshold = hiddenAppMem;
5531        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5532                ProcessList.SERVICE_ADJ);
5533        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5534                ProcessList.VISIBLE_APP_ADJ);
5535        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5536                ProcessList.FOREGROUND_APP_ADJ);
5537    }
5538
5539    // =========================================================
5540    // TASK MANAGEMENT
5541    // =========================================================
5542
5543    public List getTasks(int maxNum, int flags,
5544                         IThumbnailReceiver receiver) {
5545        ArrayList list = new ArrayList();
5546
5547        PendingThumbnailsRecord pending = null;
5548        IApplicationThread topThumbnail = null;
5549        ActivityRecord topRecord = null;
5550
5551        synchronized(this) {
5552            if (localLOGV) Slog.v(
5553                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5554                + ", receiver=" + receiver);
5555
5556            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5557                    != PackageManager.PERMISSION_GRANTED) {
5558                if (receiver != null) {
5559                    // If the caller wants to wait for pending thumbnails,
5560                    // it ain't gonna get them.
5561                    try {
5562                        receiver.finished();
5563                    } catch (RemoteException ex) {
5564                    }
5565                }
5566                String msg = "Permission Denial: getTasks() from pid="
5567                        + Binder.getCallingPid()
5568                        + ", uid=" + Binder.getCallingUid()
5569                        + " requires " + android.Manifest.permission.GET_TASKS;
5570                Slog.w(TAG, msg);
5571                throw new SecurityException(msg);
5572            }
5573
5574            int pos = mMainStack.mHistory.size()-1;
5575            ActivityRecord next =
5576                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5577            ActivityRecord top = null;
5578            TaskRecord curTask = null;
5579            int numActivities = 0;
5580            int numRunning = 0;
5581            while (pos >= 0 && maxNum > 0) {
5582                final ActivityRecord r = next;
5583                pos--;
5584                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5585
5586                // Initialize state for next task if needed.
5587                if (top == null ||
5588                        (top.state == ActivityState.INITIALIZING
5589                            && top.task == r.task)) {
5590                    top = r;
5591                    curTask = r.task;
5592                    numActivities = numRunning = 0;
5593                }
5594
5595                // Add 'r' into the current task.
5596                numActivities++;
5597                if (r.app != null && r.app.thread != null) {
5598                    numRunning++;
5599                }
5600
5601                if (localLOGV) Slog.v(
5602                    TAG, r.intent.getComponent().flattenToShortString()
5603                    + ": task=" + r.task);
5604
5605                // If the next one is a different task, generate a new
5606                // TaskInfo entry for what we have.
5607                if (next == null || next.task != curTask) {
5608                    ActivityManager.RunningTaskInfo ci
5609                            = new ActivityManager.RunningTaskInfo();
5610                    ci.id = curTask.taskId;
5611                    ci.baseActivity = r.intent.getComponent();
5612                    ci.topActivity = top.intent.getComponent();
5613                    if (top.thumbHolder != null) {
5614                        ci.description = top.thumbHolder.lastDescription;
5615                    }
5616                    ci.numActivities = numActivities;
5617                    ci.numRunning = numRunning;
5618                    //System.out.println(
5619                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5620                    if (ci.thumbnail == null && receiver != null) {
5621                        if (localLOGV) Slog.v(
5622                            TAG, "State=" + top.state + "Idle=" + top.idle
5623                            + " app=" + top.app
5624                            + " thr=" + (top.app != null ? top.app.thread : null));
5625                        if (top.state == ActivityState.RESUMED
5626                                || top.state == ActivityState.PAUSING) {
5627                            if (top.idle && top.app != null
5628                                && top.app.thread != null) {
5629                                topRecord = top;
5630                                topThumbnail = top.app.thread;
5631                            } else {
5632                                top.thumbnailNeeded = true;
5633                            }
5634                        }
5635                        if (pending == null) {
5636                            pending = new PendingThumbnailsRecord(receiver);
5637                        }
5638                        pending.pendingRecords.add(top);
5639                    }
5640                    list.add(ci);
5641                    maxNum--;
5642                    top = null;
5643                }
5644            }
5645
5646            if (pending != null) {
5647                mPendingThumbnails.add(pending);
5648            }
5649        }
5650
5651        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5652
5653        if (topThumbnail != null) {
5654            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5655            try {
5656                topThumbnail.requestThumbnail(topRecord.appToken);
5657            } catch (Exception e) {
5658                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5659                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5660            }
5661        }
5662
5663        if (pending == null && receiver != null) {
5664            // In this case all thumbnails were available and the client
5665            // is being asked to be told when the remaining ones come in...
5666            // which is unusually, since the top-most currently running
5667            // activity should never have a canned thumbnail!  Oh well.
5668            try {
5669                receiver.finished();
5670            } catch (RemoteException ex) {
5671            }
5672        }
5673
5674        return list;
5675    }
5676
5677    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5678            int flags, int userId) {
5679        final int callingUid = Binder.getCallingUid();
5680        if (userId != UserHandle.getCallingUserId()) {
5681            // Check if the caller is holding permissions for cross-user requests.
5682            if (checkComponentPermission(
5683                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5684                    Binder.getCallingPid(), callingUid, -1, true)
5685                    != PackageManager.PERMISSION_GRANTED) {
5686                String msg = "Permission Denial: "
5687                        + "Request to get recent tasks for user " + userId
5688                        + " but is calling from user " + UserHandle.getUserId(callingUid)
5689                        + "; this requires "
5690                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5691                Slog.w(TAG, msg);
5692                throw new SecurityException(msg);
5693            } else {
5694                if (userId == UserHandle.USER_CURRENT) {
5695                    userId = mCurrentUserId;
5696                }
5697            }
5698        }
5699
5700        synchronized (this) {
5701            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5702                    "getRecentTasks()");
5703            final boolean detailed = checkCallingPermission(
5704                    android.Manifest.permission.GET_DETAILED_TASKS)
5705                    == PackageManager.PERMISSION_GRANTED;
5706
5707            IPackageManager pm = AppGlobals.getPackageManager();
5708
5709            final int N = mRecentTasks.size();
5710            ArrayList<ActivityManager.RecentTaskInfo> res
5711                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5712                            maxNum < N ? maxNum : N);
5713            for (int i=0; i<N && maxNum > 0; i++) {
5714                TaskRecord tr = mRecentTasks.get(i);
5715                // Only add calling user's recent tasks
5716                if (tr.userId != userId) continue;
5717                // Return the entry if desired by the caller.  We always return
5718                // the first entry, because callers always expect this to be the
5719                // foreground app.  We may filter others if the caller has
5720                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5721                // we should exclude the entry.
5722
5723                if (i == 0
5724                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5725                        || (tr.intent == null)
5726                        || ((tr.intent.getFlags()
5727                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5728                    ActivityManager.RecentTaskInfo rti
5729                            = new ActivityManager.RecentTaskInfo();
5730                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5731                    rti.persistentId = tr.taskId;
5732                    rti.baseIntent = new Intent(
5733                            tr.intent != null ? tr.intent : tr.affinityIntent);
5734                    if (!detailed) {
5735                        rti.baseIntent.replaceExtras((Bundle)null);
5736                    }
5737                    rti.origActivity = tr.origActivity;
5738                    rti.description = tr.lastDescription;
5739
5740                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5741                        // Check whether this activity is currently available.
5742                        try {
5743                            if (rti.origActivity != null) {
5744                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5745                                        == null) {
5746                                    continue;
5747                                }
5748                            } else if (rti.baseIntent != null) {
5749                                if (pm.queryIntentActivities(rti.baseIntent,
5750                                        null, 0, userId) == null) {
5751                                    continue;
5752                                }
5753                            }
5754                        } catch (RemoteException e) {
5755                            // Will never happen.
5756                        }
5757                    }
5758
5759                    res.add(rti);
5760                    maxNum--;
5761                }
5762            }
5763            return res;
5764        }
5765    }
5766
5767    private TaskRecord taskForIdLocked(int id) {
5768        final int N = mRecentTasks.size();
5769        for (int i=0; i<N; i++) {
5770            TaskRecord tr = mRecentTasks.get(i);
5771            if (tr.taskId == id) {
5772                return tr;
5773            }
5774        }
5775        return null;
5776    }
5777
5778    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5779        synchronized (this) {
5780            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5781                    "getTaskThumbnails()");
5782            TaskRecord tr = taskForIdLocked(id);
5783            if (tr != null) {
5784                return mMainStack.getTaskThumbnailsLocked(tr);
5785            }
5786        }
5787        return null;
5788    }
5789
5790    public boolean removeSubTask(int taskId, int subTaskIndex) {
5791        synchronized (this) {
5792            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5793                    "removeSubTask()");
5794            long ident = Binder.clearCallingIdentity();
5795            try {
5796                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5797                        true) != null;
5798            } finally {
5799                Binder.restoreCallingIdentity(ident);
5800            }
5801        }
5802    }
5803
5804    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5805        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5806        Intent baseIntent = new Intent(
5807                tr.intent != null ? tr.intent : tr.affinityIntent);
5808        ComponentName component = baseIntent.getComponent();
5809        if (component == null) {
5810            Slog.w(TAG, "Now component for base intent of task: " + tr);
5811            return;
5812        }
5813
5814        // Find any running services associated with this app.
5815        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5816
5817        if (killProcesses) {
5818            // Find any running processes associated with this app.
5819            final String pkg = component.getPackageName();
5820            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5821            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5822            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5823                for (int i=0; i<uids.size(); i++) {
5824                    ProcessRecord proc = uids.valueAt(i);
5825                    if (proc.userId != tr.userId) {
5826                        continue;
5827                    }
5828                    if (!proc.pkgList.contains(pkg)) {
5829                        continue;
5830                    }
5831                    procs.add(proc);
5832                }
5833            }
5834
5835            // Kill the running processes.
5836            for (int i=0; i<procs.size(); i++) {
5837                ProcessRecord pr = procs.get(i);
5838                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5839                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5840                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5841                            pr.processName, pr.setAdj, "remove task");
5842                    pr.killedBackground = true;
5843                    Process.killProcessQuiet(pr.pid);
5844                } else {
5845                    pr.waitingToKill = "remove task";
5846                }
5847            }
5848        }
5849    }
5850
5851    public boolean removeTask(int taskId, int flags) {
5852        synchronized (this) {
5853            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5854                    "removeTask()");
5855            long ident = Binder.clearCallingIdentity();
5856            try {
5857                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5858                        false);
5859                if (r != null) {
5860                    mRecentTasks.remove(r.task);
5861                    cleanUpRemovedTaskLocked(r.task, flags);
5862                    return true;
5863                } else {
5864                    TaskRecord tr = null;
5865                    int i=0;
5866                    while (i < mRecentTasks.size()) {
5867                        TaskRecord t = mRecentTasks.get(i);
5868                        if (t.taskId == taskId) {
5869                            tr = t;
5870                            break;
5871                        }
5872                        i++;
5873                    }
5874                    if (tr != null) {
5875                        if (tr.numActivities <= 0) {
5876                            // Caller is just removing a recent task that is
5877                            // not actively running.  That is easy!
5878                            mRecentTasks.remove(i);
5879                            cleanUpRemovedTaskLocked(tr, flags);
5880                            return true;
5881                        } else {
5882                            Slog.w(TAG, "removeTask: task " + taskId
5883                                    + " does not have activities to remove, "
5884                                    + " but numActivities=" + tr.numActivities
5885                                    + ": " + tr);
5886                        }
5887                    }
5888                }
5889            } finally {
5890                Binder.restoreCallingIdentity(ident);
5891            }
5892        }
5893        return false;
5894    }
5895
5896    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5897        int j;
5898        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5899        TaskRecord jt = startTask;
5900
5901        // First look backwards
5902        for (j=startIndex-1; j>=0; j--) {
5903            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5904            if (r.task != jt) {
5905                jt = r.task;
5906                if (affinity.equals(jt.affinity)) {
5907                    return j;
5908                }
5909            }
5910        }
5911
5912        // Now look forwards
5913        final int N = mMainStack.mHistory.size();
5914        jt = startTask;
5915        for (j=startIndex+1; j<N; j++) {
5916            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5917            if (r.task != jt) {
5918                if (affinity.equals(jt.affinity)) {
5919                    return j;
5920                }
5921                jt = r.task;
5922            }
5923        }
5924
5925        // Might it be at the top?
5926        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5927            return N-1;
5928        }
5929
5930        return -1;
5931    }
5932
5933    /**
5934     * TODO: Add mController hook
5935     */
5936    public void moveTaskToFront(int task, int flags, Bundle options) {
5937        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5938                "moveTaskToFront()");
5939
5940        synchronized(this) {
5941            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5942                    Binder.getCallingUid(), "Task to front")) {
5943                ActivityOptions.abort(options);
5944                return;
5945            }
5946            final long origId = Binder.clearCallingIdentity();
5947            try {
5948                TaskRecord tr = taskForIdLocked(task);
5949                if (tr != null) {
5950                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5951                        mMainStack.mUserLeaving = true;
5952                    }
5953                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5954                        // Caller wants the home activity moved with it.  To accomplish this,
5955                        // we'll just move the home task to the top first.
5956                        mMainStack.moveHomeToFrontLocked();
5957                    }
5958                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5959                    return;
5960                }
5961                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5962                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5963                    if (hr.task.taskId == task) {
5964                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5965                            mMainStack.mUserLeaving = true;
5966                        }
5967                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5968                            // Caller wants the home activity moved with it.  To accomplish this,
5969                            // we'll just move the home task to the top first.
5970                            mMainStack.moveHomeToFrontLocked();
5971                        }
5972                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5973                        return;
5974                    }
5975                }
5976            } finally {
5977                Binder.restoreCallingIdentity(origId);
5978            }
5979            ActivityOptions.abort(options);
5980        }
5981    }
5982
5983    public void moveTaskToBack(int task) {
5984        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5985                "moveTaskToBack()");
5986
5987        synchronized(this) {
5988            if (mMainStack.mResumedActivity != null
5989                    && mMainStack.mResumedActivity.task.taskId == task) {
5990                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5991                        Binder.getCallingUid(), "Task to back")) {
5992                    return;
5993                }
5994            }
5995            final long origId = Binder.clearCallingIdentity();
5996            mMainStack.moveTaskToBackLocked(task, null);
5997            Binder.restoreCallingIdentity(origId);
5998        }
5999    }
6000
6001    /**
6002     * Moves an activity, and all of the other activities within the same task, to the bottom
6003     * of the history stack.  The activity's order within the task is unchanged.
6004     *
6005     * @param token A reference to the activity we wish to move
6006     * @param nonRoot If false then this only works if the activity is the root
6007     *                of a task; if true it will work for any activity in a task.
6008     * @return Returns true if the move completed, false if not.
6009     */
6010    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6011        enforceNotIsolatedCaller("moveActivityTaskToBack");
6012        synchronized(this) {
6013            final long origId = Binder.clearCallingIdentity();
6014            int taskId = getTaskForActivityLocked(token, !nonRoot);
6015            if (taskId >= 0) {
6016                return mMainStack.moveTaskToBackLocked(taskId, null);
6017            }
6018            Binder.restoreCallingIdentity(origId);
6019        }
6020        return false;
6021    }
6022
6023    public void moveTaskBackwards(int task) {
6024        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6025                "moveTaskBackwards()");
6026
6027        synchronized(this) {
6028            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6029                    Binder.getCallingUid(), "Task backwards")) {
6030                return;
6031            }
6032            final long origId = Binder.clearCallingIdentity();
6033            moveTaskBackwardsLocked(task);
6034            Binder.restoreCallingIdentity(origId);
6035        }
6036    }
6037
6038    private final void moveTaskBackwardsLocked(int task) {
6039        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
6040    }
6041
6042    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6043        synchronized(this) {
6044            return getTaskForActivityLocked(token, onlyRoot);
6045        }
6046    }
6047
6048    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6049        final int N = mMainStack.mHistory.size();
6050        TaskRecord lastTask = null;
6051        for (int i=0; i<N; i++) {
6052            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6053            if (r.appToken == token) {
6054                if (!onlyRoot || lastTask != r.task) {
6055                    return r.task.taskId;
6056                }
6057                return -1;
6058            }
6059            lastTask = r.task;
6060        }
6061
6062        return -1;
6063    }
6064
6065    // =========================================================
6066    // THUMBNAILS
6067    // =========================================================
6068
6069    public void reportThumbnail(IBinder token,
6070            Bitmap thumbnail, CharSequence description) {
6071        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6072        final long origId = Binder.clearCallingIdentity();
6073        sendPendingThumbnail(null, token, thumbnail, description, true);
6074        Binder.restoreCallingIdentity(origId);
6075    }
6076
6077    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6078            Bitmap thumbnail, CharSequence description, boolean always) {
6079        TaskRecord task = null;
6080        ArrayList receivers = null;
6081
6082        //System.out.println("Send pending thumbnail: " + r);
6083
6084        synchronized(this) {
6085            if (r == null) {
6086                r = mMainStack.isInStackLocked(token);
6087                if (r == null) {
6088                    return;
6089                }
6090            }
6091            if (thumbnail == null && r.thumbHolder != null) {
6092                thumbnail = r.thumbHolder.lastThumbnail;
6093                description = r.thumbHolder.lastDescription;
6094            }
6095            if (thumbnail == null && !always) {
6096                // If there is no thumbnail, and this entry is not actually
6097                // going away, then abort for now and pick up the next
6098                // thumbnail we get.
6099                return;
6100            }
6101            task = r.task;
6102
6103            int N = mPendingThumbnails.size();
6104            int i=0;
6105            while (i<N) {
6106                PendingThumbnailsRecord pr =
6107                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6108                //System.out.println("Looking in " + pr.pendingRecords);
6109                if (pr.pendingRecords.remove(r)) {
6110                    if (receivers == null) {
6111                        receivers = new ArrayList();
6112                    }
6113                    receivers.add(pr);
6114                    if (pr.pendingRecords.size() == 0) {
6115                        pr.finished = true;
6116                        mPendingThumbnails.remove(i);
6117                        N--;
6118                        continue;
6119                    }
6120                }
6121                i++;
6122            }
6123        }
6124
6125        if (receivers != null) {
6126            final int N = receivers.size();
6127            for (int i=0; i<N; i++) {
6128                try {
6129                    PendingThumbnailsRecord pr =
6130                        (PendingThumbnailsRecord)receivers.get(i);
6131                    pr.receiver.newThumbnail(
6132                        task != null ? task.taskId : -1, thumbnail, description);
6133                    if (pr.finished) {
6134                        pr.receiver.finished();
6135                    }
6136                } catch (Exception e) {
6137                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6138                }
6139            }
6140        }
6141    }
6142
6143    // =========================================================
6144    // CONTENT PROVIDERS
6145    // =========================================================
6146
6147    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6148        List<ProviderInfo> providers = null;
6149        try {
6150            providers = AppGlobals.getPackageManager().
6151                queryContentProviders(app.processName, app.uid,
6152                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6153        } catch (RemoteException ex) {
6154        }
6155        if (DEBUG_MU)
6156            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6157        int userId = app.userId;
6158        if (providers != null) {
6159            int N = providers.size();
6160            for (int i=0; i<N; i++) {
6161                ProviderInfo cpi =
6162                    (ProviderInfo)providers.get(i);
6163                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6164                        cpi.name, cpi.flags);
6165                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6166                    // This is a singleton provider, but a user besides the
6167                    // default user is asking to initialize a process it runs
6168                    // in...  well, no, it doesn't actually run in this process,
6169                    // it runs in the process of the default user.  Get rid of it.
6170                    providers.remove(i);
6171                    N--;
6172                    continue;
6173                }
6174
6175                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6176                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6177                if (cpr == null) {
6178                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6179                    mProviderMap.putProviderByClass(comp, cpr);
6180                }
6181                if (DEBUG_MU)
6182                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6183                app.pubProviders.put(cpi.name, cpr);
6184                app.addPackage(cpi.applicationInfo.packageName);
6185                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6186            }
6187        }
6188        return providers;
6189    }
6190
6191    /**
6192     * Check if {@link ProcessRecord} has a possible chance at accessing the
6193     * given {@link ProviderInfo}. Final permission checking is always done
6194     * in {@link ContentProvider}.
6195     */
6196    private final String checkContentProviderPermissionLocked(
6197            ProviderInfo cpi, ProcessRecord r) {
6198        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6199        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6200        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6201                cpi.applicationInfo.uid, cpi.exported)
6202                == PackageManager.PERMISSION_GRANTED) {
6203            return null;
6204        }
6205        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6206                cpi.applicationInfo.uid, cpi.exported)
6207                == PackageManager.PERMISSION_GRANTED) {
6208            return null;
6209        }
6210
6211        PathPermission[] pps = cpi.pathPermissions;
6212        if (pps != null) {
6213            int i = pps.length;
6214            while (i > 0) {
6215                i--;
6216                PathPermission pp = pps[i];
6217                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6218                        cpi.applicationInfo.uid, cpi.exported)
6219                        == PackageManager.PERMISSION_GRANTED) {
6220                    return null;
6221                }
6222                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6223                        cpi.applicationInfo.uid, cpi.exported)
6224                        == PackageManager.PERMISSION_GRANTED) {
6225                    return null;
6226                }
6227            }
6228        }
6229
6230        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6231        if (perms != null) {
6232            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6233                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6234                    return null;
6235                }
6236            }
6237        }
6238
6239        String msg;
6240        if (!cpi.exported) {
6241            msg = "Permission Denial: opening provider " + cpi.name
6242                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6243                    + ", uid=" + callingUid + ") that is not exported from uid "
6244                    + cpi.applicationInfo.uid;
6245        } else {
6246            msg = "Permission Denial: opening provider " + cpi.name
6247                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6248                    + ", uid=" + callingUid + ") requires "
6249                    + cpi.readPermission + " or " + cpi.writePermission;
6250        }
6251        Slog.w(TAG, msg);
6252        return msg;
6253    }
6254
6255    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6256            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6257        if (r != null) {
6258            for (int i=0; i<r.conProviders.size(); i++) {
6259                ContentProviderConnection conn = r.conProviders.get(i);
6260                if (conn.provider == cpr) {
6261                    if (DEBUG_PROVIDER) Slog.v(TAG,
6262                            "Adding provider requested by "
6263                            + r.processName + " from process "
6264                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6265                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6266                    if (stable) {
6267                        conn.stableCount++;
6268                        conn.numStableIncs++;
6269                    } else {
6270                        conn.unstableCount++;
6271                        conn.numUnstableIncs++;
6272                    }
6273                    return conn;
6274                }
6275            }
6276            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6277            if (stable) {
6278                conn.stableCount = 1;
6279                conn.numStableIncs = 1;
6280            } else {
6281                conn.unstableCount = 1;
6282                conn.numUnstableIncs = 1;
6283            }
6284            cpr.connections.add(conn);
6285            r.conProviders.add(conn);
6286            return conn;
6287        }
6288        cpr.addExternalProcessHandleLocked(externalProcessToken);
6289        return null;
6290    }
6291
6292    boolean decProviderCountLocked(ContentProviderConnection conn,
6293            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6294        if (conn != null) {
6295            cpr = conn.provider;
6296            if (DEBUG_PROVIDER) Slog.v(TAG,
6297                    "Removing provider requested by "
6298                    + conn.client.processName + " from process "
6299                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6300                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6301            if (stable) {
6302                conn.stableCount--;
6303            } else {
6304                conn.unstableCount--;
6305            }
6306            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6307                cpr.connections.remove(conn);
6308                conn.client.conProviders.remove(conn);
6309                return true;
6310            }
6311            return false;
6312        }
6313        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6314        return false;
6315    }
6316
6317    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6318            String name, IBinder token, boolean stable, int userId) {
6319        ContentProviderRecord cpr;
6320        ContentProviderConnection conn = null;
6321        ProviderInfo cpi = null;
6322
6323        synchronized(this) {
6324            ProcessRecord r = null;
6325            if (caller != null) {
6326                r = getRecordForAppLocked(caller);
6327                if (r == null) {
6328                    throw new SecurityException(
6329                            "Unable to find app for caller " + caller
6330                          + " (pid=" + Binder.getCallingPid()
6331                          + ") when getting content provider " + name);
6332                }
6333                if (r.userId != userId) {
6334                    throw new SecurityException("Calling requested user " + userId
6335                            + " but app is user " + r.userId);
6336                }
6337            }
6338
6339            // First check if this content provider has been published...
6340            cpr = mProviderMap.getProviderByName(name, userId);
6341            boolean providerRunning = cpr != null;
6342            if (providerRunning) {
6343                cpi = cpr.info;
6344                String msg;
6345                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6346                    throw new SecurityException(msg);
6347                }
6348
6349                if (r != null && cpr.canRunHere(r)) {
6350                    // This provider has been published or is in the process
6351                    // of being published...  but it is also allowed to run
6352                    // in the caller's process, so don't make a connection
6353                    // and just let the caller instantiate its own instance.
6354                    ContentProviderHolder holder = cpr.newHolder(null);
6355                    // don't give caller the provider object, it needs
6356                    // to make its own.
6357                    holder.provider = null;
6358                    return holder;
6359                }
6360
6361                final long origId = Binder.clearCallingIdentity();
6362
6363                // In this case the provider instance already exists, so we can
6364                // return it right away.
6365                conn = incProviderCountLocked(r, cpr, token, stable);
6366                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6367                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6368                        // If this is a perceptible app accessing the provider,
6369                        // make sure to count it as being accessed and thus
6370                        // back up on the LRU list.  This is good because
6371                        // content providers are often expensive to start.
6372                        updateLruProcessLocked(cpr.proc, false, true);
6373                    }
6374                }
6375
6376                if (cpr.proc != null) {
6377                    if (false) {
6378                        if (cpr.name.flattenToShortString().equals(
6379                                "com.android.providers.calendar/.CalendarProvider2")) {
6380                            Slog.v(TAG, "****************** KILLING "
6381                                + cpr.name.flattenToShortString());
6382                            Process.killProcess(cpr.proc.pid);
6383                        }
6384                    }
6385                    boolean success = updateOomAdjLocked(cpr.proc);
6386                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6387                    // NOTE: there is still a race here where a signal could be
6388                    // pending on the process even though we managed to update its
6389                    // adj level.  Not sure what to do about this, but at least
6390                    // the race is now smaller.
6391                    if (!success) {
6392                        // Uh oh...  it looks like the provider's process
6393                        // has been killed on us.  We need to wait for a new
6394                        // process to be started, and make sure its death
6395                        // doesn't kill our process.
6396                        Slog.i(TAG,
6397                                "Existing provider " + cpr.name.flattenToShortString()
6398                                + " is crashing; detaching " + r);
6399                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6400                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6401                        if (!lastRef) {
6402                            // This wasn't the last ref our process had on
6403                            // the provider...  we have now been killed, bail.
6404                            return null;
6405                        }
6406                        providerRunning = false;
6407                        conn = null;
6408                    }
6409                }
6410
6411                Binder.restoreCallingIdentity(origId);
6412            }
6413
6414            boolean singleton;
6415            if (!providerRunning) {
6416                try {
6417                    cpi = AppGlobals.getPackageManager().
6418                        resolveContentProvider(name,
6419                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6420                } catch (RemoteException ex) {
6421                }
6422                if (cpi == null) {
6423                    return null;
6424                }
6425                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6426                        cpi.name, cpi.flags);
6427                if (singleton) {
6428                    userId = 0;
6429                }
6430                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6431
6432                String msg;
6433                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6434                    throw new SecurityException(msg);
6435                }
6436
6437                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6438                        && !cpi.processName.equals("system")) {
6439                    // If this content provider does not run in the system
6440                    // process, and the system is not yet ready to run other
6441                    // processes, then fail fast instead of hanging.
6442                    throw new IllegalArgumentException(
6443                            "Attempt to launch content provider before system ready");
6444                }
6445
6446                // Make sure that the user who owns this provider is started.  If not,
6447                // we don't want to allow it to run.
6448                if (mStartedUsers.get(userId) == null) {
6449                    Slog.w(TAG, "Unable to launch app "
6450                            + cpi.applicationInfo.packageName + "/"
6451                            + cpi.applicationInfo.uid + " for provider "
6452                            + name + ": user " + userId + " is stopped");
6453                    return null;
6454                }
6455
6456                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6457                cpr = mProviderMap.getProviderByClass(comp, userId);
6458                final boolean firstClass = cpr == null;
6459                if (firstClass) {
6460                    try {
6461                        ApplicationInfo ai =
6462                            AppGlobals.getPackageManager().
6463                                getApplicationInfo(
6464                                        cpi.applicationInfo.packageName,
6465                                        STOCK_PM_FLAGS, userId);
6466                        if (ai == null) {
6467                            Slog.w(TAG, "No package info for content provider "
6468                                    + cpi.name);
6469                            return null;
6470                        }
6471                        ai = getAppInfoForUser(ai, userId);
6472                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6473                    } catch (RemoteException ex) {
6474                        // pm is in same process, this will never happen.
6475                    }
6476                }
6477
6478                if (r != null && cpr.canRunHere(r)) {
6479                    // If this is a multiprocess provider, then just return its
6480                    // info and allow the caller to instantiate it.  Only do
6481                    // this if the provider is the same user as the caller's
6482                    // process, or can run as root (so can be in any process).
6483                    return cpr.newHolder(null);
6484                }
6485
6486                if (DEBUG_PROVIDER) {
6487                    RuntimeException e = new RuntimeException("here");
6488                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6489                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6490                }
6491
6492                // This is single process, and our app is now connecting to it.
6493                // See if we are already in the process of launching this
6494                // provider.
6495                final int N = mLaunchingProviders.size();
6496                int i;
6497                for (i=0; i<N; i++) {
6498                    if (mLaunchingProviders.get(i) == cpr) {
6499                        break;
6500                    }
6501                }
6502
6503                // If the provider is not already being launched, then get it
6504                // started.
6505                if (i >= N) {
6506                    final long origId = Binder.clearCallingIdentity();
6507
6508                    try {
6509                        // Content provider is now in use, its package can't be stopped.
6510                        try {
6511                            AppGlobals.getPackageManager().setPackageStoppedState(
6512                                    cpr.appInfo.packageName, false, userId);
6513                        } catch (RemoteException e) {
6514                        } catch (IllegalArgumentException e) {
6515                            Slog.w(TAG, "Failed trying to unstop package "
6516                                    + cpr.appInfo.packageName + ": " + e);
6517                        }
6518
6519                        ProcessRecord proc = startProcessLocked(cpi.processName,
6520                                cpr.appInfo, false, 0, "content provider",
6521                                new ComponentName(cpi.applicationInfo.packageName,
6522                                        cpi.name), false, false);
6523                        if (proc == null) {
6524                            Slog.w(TAG, "Unable to launch app "
6525                                    + cpi.applicationInfo.packageName + "/"
6526                                    + cpi.applicationInfo.uid + " for provider "
6527                                    + name + ": process is bad");
6528                            return null;
6529                        }
6530                        cpr.launchingApp = proc;
6531                        mLaunchingProviders.add(cpr);
6532                    } finally {
6533                        Binder.restoreCallingIdentity(origId);
6534                    }
6535                }
6536
6537                // Make sure the provider is published (the same provider class
6538                // may be published under multiple names).
6539                if (firstClass) {
6540                    mProviderMap.putProviderByClass(comp, cpr);
6541                }
6542
6543                mProviderMap.putProviderByName(name, cpr);
6544                conn = incProviderCountLocked(r, cpr, token, stable);
6545                if (conn != null) {
6546                    conn.waiting = true;
6547                }
6548            }
6549        }
6550
6551        // Wait for the provider to be published...
6552        synchronized (cpr) {
6553            while (cpr.provider == null) {
6554                if (cpr.launchingApp == null) {
6555                    Slog.w(TAG, "Unable to launch app "
6556                            + cpi.applicationInfo.packageName + "/"
6557                            + cpi.applicationInfo.uid + " for provider "
6558                            + name + ": launching app became null");
6559                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6560                            cpi.applicationInfo.packageName,
6561                            cpi.applicationInfo.uid, name);
6562                    return null;
6563                }
6564                try {
6565                    if (DEBUG_MU) {
6566                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6567                                + cpr.launchingApp);
6568                    }
6569                    if (conn != null) {
6570                        conn.waiting = true;
6571                    }
6572                    cpr.wait();
6573                } catch (InterruptedException ex) {
6574                } finally {
6575                    if (conn != null) {
6576                        conn.waiting = false;
6577                    }
6578                }
6579            }
6580        }
6581        return cpr != null ? cpr.newHolder(conn) : null;
6582    }
6583
6584    public final ContentProviderHolder getContentProvider(
6585            IApplicationThread caller, String name, boolean stable) {
6586        enforceNotIsolatedCaller("getContentProvider");
6587        if (caller == null) {
6588            String msg = "null IApplicationThread when getting content provider "
6589                    + name;
6590            Slog.w(TAG, msg);
6591            throw new SecurityException(msg);
6592        }
6593
6594        return getContentProviderImpl(caller, name, null, stable,
6595                UserHandle.getCallingUserId());
6596    }
6597
6598    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6599        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6600            "Do not have permission in call getContentProviderExternal()");
6601        return getContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6602    }
6603
6604    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6605            IBinder token, int userId) {
6606        return getContentProviderImpl(null, name, token, true, userId);
6607    }
6608
6609    /**
6610     * Drop a content provider from a ProcessRecord's bookkeeping
6611     * @param cpr
6612     */
6613    public void removeContentProvider(IBinder connection, boolean stable) {
6614        enforceNotIsolatedCaller("removeContentProvider");
6615        synchronized (this) {
6616            ContentProviderConnection conn;
6617            try {
6618                conn = (ContentProviderConnection)connection;
6619            } catch (ClassCastException e) {
6620                String msg ="removeContentProvider: " + connection
6621                        + " not a ContentProviderConnection";
6622                Slog.w(TAG, msg);
6623                throw new IllegalArgumentException(msg);
6624            }
6625            if (conn == null) {
6626                throw new NullPointerException("connection is null");
6627            }
6628            if (decProviderCountLocked(conn, null, null, stable)) {
6629                updateOomAdjLocked();
6630            }
6631        }
6632    }
6633
6634    public void removeContentProviderExternal(String name, IBinder token) {
6635        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6636            "Do not have permission in call removeContentProviderExternal()");
6637        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6638    }
6639
6640    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6641        synchronized (this) {
6642            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6643            if(cpr == null) {
6644                //remove from mProvidersByClass
6645                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6646                return;
6647            }
6648
6649            //update content provider record entry info
6650            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6651            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6652            if (localCpr.hasExternalProcessHandles()) {
6653                if (localCpr.removeExternalProcessHandleLocked(token)) {
6654                    updateOomAdjLocked();
6655                } else {
6656                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6657                            + " with no external reference for token: "
6658                            + token + ".");
6659                }
6660            } else {
6661                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6662                        + " with no external references.");
6663            }
6664        }
6665    }
6666
6667    public final void publishContentProviders(IApplicationThread caller,
6668            List<ContentProviderHolder> providers) {
6669        if (providers == null) {
6670            return;
6671        }
6672
6673        enforceNotIsolatedCaller("publishContentProviders");
6674        synchronized (this) {
6675            final ProcessRecord r = getRecordForAppLocked(caller);
6676            if (DEBUG_MU)
6677                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6678            if (r == null) {
6679                throw new SecurityException(
6680                        "Unable to find app for caller " + caller
6681                      + " (pid=" + Binder.getCallingPid()
6682                      + ") when publishing content providers");
6683            }
6684
6685            final long origId = Binder.clearCallingIdentity();
6686
6687            final int N = providers.size();
6688            for (int i=0; i<N; i++) {
6689                ContentProviderHolder src = providers.get(i);
6690                if (src == null || src.info == null || src.provider == null) {
6691                    continue;
6692                }
6693                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6694                if (DEBUG_MU)
6695                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6696                if (dst != null) {
6697                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6698                    mProviderMap.putProviderByClass(comp, dst);
6699                    String names[] = dst.info.authority.split(";");
6700                    for (int j = 0; j < names.length; j++) {
6701                        mProviderMap.putProviderByName(names[j], dst);
6702                    }
6703
6704                    int NL = mLaunchingProviders.size();
6705                    int j;
6706                    for (j=0; j<NL; j++) {
6707                        if (mLaunchingProviders.get(j) == dst) {
6708                            mLaunchingProviders.remove(j);
6709                            j--;
6710                            NL--;
6711                        }
6712                    }
6713                    synchronized (dst) {
6714                        dst.provider = src.provider;
6715                        dst.proc = r;
6716                        dst.notifyAll();
6717                    }
6718                    updateOomAdjLocked(r);
6719                }
6720            }
6721
6722            Binder.restoreCallingIdentity(origId);
6723        }
6724    }
6725
6726    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6727        ContentProviderConnection conn;
6728        try {
6729            conn = (ContentProviderConnection)connection;
6730        } catch (ClassCastException e) {
6731            String msg ="refContentProvider: " + connection
6732                    + " not a ContentProviderConnection";
6733            Slog.w(TAG, msg);
6734            throw new IllegalArgumentException(msg);
6735        }
6736        if (conn == null) {
6737            throw new NullPointerException("connection is null");
6738        }
6739
6740        synchronized (this) {
6741            if (stable > 0) {
6742                conn.numStableIncs += stable;
6743            }
6744            stable = conn.stableCount + stable;
6745            if (stable < 0) {
6746                throw new IllegalStateException("stableCount < 0: " + stable);
6747            }
6748
6749            if (unstable > 0) {
6750                conn.numUnstableIncs += unstable;
6751            }
6752            unstable = conn.unstableCount + unstable;
6753            if (unstable < 0) {
6754                throw new IllegalStateException("unstableCount < 0: " + unstable);
6755            }
6756
6757            if ((stable+unstable) <= 0) {
6758                throw new IllegalStateException("ref counts can't go to zero here: stable="
6759                        + stable + " unstable=" + unstable);
6760            }
6761            conn.stableCount = stable;
6762            conn.unstableCount = unstable;
6763            return !conn.dead;
6764        }
6765    }
6766
6767    public void unstableProviderDied(IBinder connection) {
6768        ContentProviderConnection conn;
6769        try {
6770            conn = (ContentProviderConnection)connection;
6771        } catch (ClassCastException e) {
6772            String msg ="refContentProvider: " + connection
6773                    + " not a ContentProviderConnection";
6774            Slog.w(TAG, msg);
6775            throw new IllegalArgumentException(msg);
6776        }
6777        if (conn == null) {
6778            throw new NullPointerException("connection is null");
6779        }
6780
6781        // Safely retrieve the content provider associated with the connection.
6782        IContentProvider provider;
6783        synchronized (this) {
6784            provider = conn.provider.provider;
6785        }
6786
6787        if (provider == null) {
6788            // Um, yeah, we're way ahead of you.
6789            return;
6790        }
6791
6792        // Make sure the caller is being honest with us.
6793        if (provider.asBinder().pingBinder()) {
6794            // Er, no, still looks good to us.
6795            synchronized (this) {
6796                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6797                        + " says " + conn + " died, but we don't agree");
6798                return;
6799            }
6800        }
6801
6802        // Well look at that!  It's dead!
6803        synchronized (this) {
6804            if (conn.provider.provider != provider) {
6805                // But something changed...  good enough.
6806                return;
6807            }
6808
6809            ProcessRecord proc = conn.provider.proc;
6810            if (proc == null || proc.thread == null) {
6811                // Seems like the process is already cleaned up.
6812                return;
6813            }
6814
6815            // As far as we're concerned, this is just like receiving a
6816            // death notification...  just a bit prematurely.
6817            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6818                    + ") early provider death");
6819            final long ident = Binder.clearCallingIdentity();
6820            try {
6821                appDiedLocked(proc, proc.pid, proc.thread);
6822            } finally {
6823                Binder.restoreCallingIdentity(ident);
6824            }
6825        }
6826    }
6827
6828    public static final void installSystemProviders() {
6829        List<ProviderInfo> providers;
6830        synchronized (mSelf) {
6831            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6832            providers = mSelf.generateApplicationProvidersLocked(app);
6833            if (providers != null) {
6834                for (int i=providers.size()-1; i>=0; i--) {
6835                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6836                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6837                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6838                                + ": not system .apk");
6839                        providers.remove(i);
6840                    }
6841                }
6842            }
6843        }
6844        if (providers != null) {
6845            mSystemThread.installSystemProviders(providers);
6846        }
6847
6848        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6849
6850        mSelf.mUsageStatsService.monitorPackages();
6851    }
6852
6853    /**
6854     * Allows app to retrieve the MIME type of a URI without having permission
6855     * to access its content provider.
6856     *
6857     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6858     *
6859     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6860     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6861     */
6862    public String getProviderMimeType(Uri uri, int userId) {
6863        enforceNotIsolatedCaller("getProviderMimeType");
6864        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
6865                userId, false, true, "getProviderMimeType", null);
6866        final String name = uri.getAuthority();
6867        final long ident = Binder.clearCallingIdentity();
6868        ContentProviderHolder holder = null;
6869
6870        try {
6871            holder = getContentProviderExternalUnchecked(name, null, userId);
6872            if (holder != null) {
6873                return holder.provider.getType(uri);
6874            }
6875        } catch (RemoteException e) {
6876            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6877            return null;
6878        } finally {
6879            if (holder != null) {
6880                removeContentProviderExternalUnchecked(name, null, userId);
6881            }
6882            Binder.restoreCallingIdentity(ident);
6883        }
6884
6885        return null;
6886    }
6887
6888    // =========================================================
6889    // GLOBAL MANAGEMENT
6890    // =========================================================
6891
6892    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6893            ApplicationInfo info, String customProcess, boolean isolated) {
6894        String proc = customProcess != null ? customProcess : info.processName;
6895        BatteryStatsImpl.Uid.Proc ps = null;
6896        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6897        int uid = info.uid;
6898        if (isolated) {
6899            int userId = UserHandle.getUserId(uid);
6900            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6901            uid = 0;
6902            while (true) {
6903                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6904                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6905                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6906                }
6907                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6908                mNextIsolatedProcessUid++;
6909                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6910                    // No process for this uid, use it.
6911                    break;
6912                }
6913                stepsLeft--;
6914                if (stepsLeft <= 0) {
6915                    return null;
6916                }
6917            }
6918        }
6919        synchronized (stats) {
6920            ps = stats.getProcessStatsLocked(info.uid, proc);
6921        }
6922        return new ProcessRecord(ps, thread, info, proc, uid);
6923    }
6924
6925    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6926        ProcessRecord app;
6927        if (!isolated) {
6928            app = getProcessRecordLocked(info.processName, info.uid);
6929        } else {
6930            app = null;
6931        }
6932
6933        if (app == null) {
6934            app = newProcessRecordLocked(null, info, null, isolated);
6935            mProcessNames.put(info.processName, app.uid, app);
6936            if (isolated) {
6937                mIsolatedProcesses.put(app.uid, app);
6938            }
6939            updateLruProcessLocked(app, true, true);
6940        }
6941
6942        // This package really, really can not be stopped.
6943        try {
6944            AppGlobals.getPackageManager().setPackageStoppedState(
6945                    info.packageName, false, UserHandle.getUserId(app.uid));
6946        } catch (RemoteException e) {
6947        } catch (IllegalArgumentException e) {
6948            Slog.w(TAG, "Failed trying to unstop package "
6949                    + info.packageName + ": " + e);
6950        }
6951
6952        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6953                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6954            app.persistent = true;
6955            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6956        }
6957        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6958            mPersistentStartingProcesses.add(app);
6959            startProcessLocked(app, "added application", app.processName);
6960        }
6961
6962        return app;
6963    }
6964
6965    public void unhandledBack() {
6966        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6967                "unhandledBack()");
6968
6969        synchronized(this) {
6970            int count = mMainStack.mHistory.size();
6971            if (DEBUG_SWITCH) Slog.d(
6972                TAG, "Performing unhandledBack(): stack size = " + count);
6973            if (count > 1) {
6974                final long origId = Binder.clearCallingIdentity();
6975                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6976                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
6977                Binder.restoreCallingIdentity(origId);
6978            }
6979        }
6980    }
6981
6982    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6983        enforceNotIsolatedCaller("openContentUri");
6984        final int userId = UserHandle.getCallingUserId();
6985        String name = uri.getAuthority();
6986        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
6987        ParcelFileDescriptor pfd = null;
6988        if (cph != null) {
6989            // We record the binder invoker's uid in thread-local storage before
6990            // going to the content provider to open the file.  Later, in the code
6991            // that handles all permissions checks, we look for this uid and use
6992            // that rather than the Activity Manager's own uid.  The effect is that
6993            // we do the check against the caller's permissions even though it looks
6994            // to the content provider like the Activity Manager itself is making
6995            // the request.
6996            sCallerIdentity.set(new Identity(
6997                    Binder.getCallingPid(), Binder.getCallingUid()));
6998            try {
6999                pfd = cph.provider.openFile(uri, "r");
7000            } catch (FileNotFoundException e) {
7001                // do nothing; pfd will be returned null
7002            } finally {
7003                // Ensure that whatever happens, we clean up the identity state
7004                sCallerIdentity.remove();
7005            }
7006
7007            // We've got the fd now, so we're done with the provider.
7008            removeContentProviderExternalUnchecked(name, null, userId);
7009        } else {
7010            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
7011        }
7012        return pfd;
7013    }
7014
7015    // Actually is sleeping or shutting down or whatever else in the future
7016    // is an inactive state.
7017    public boolean isSleeping() {
7018        return mSleeping || mShuttingDown;
7019    }
7020
7021    public void goingToSleep() {
7022        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7023                != PackageManager.PERMISSION_GRANTED) {
7024            throw new SecurityException("Requires permission "
7025                    + android.Manifest.permission.DEVICE_POWER);
7026        }
7027
7028        synchronized(this) {
7029            mWentToSleep = true;
7030            updateEventDispatchingLocked();
7031
7032            if (!mSleeping) {
7033                mSleeping = true;
7034                mMainStack.stopIfSleepingLocked();
7035
7036                // Initialize the wake times of all processes.
7037                checkExcessivePowerUsageLocked(false);
7038                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7039                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7040                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7041            }
7042        }
7043    }
7044
7045    public boolean shutdown(int timeout) {
7046        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7047                != PackageManager.PERMISSION_GRANTED) {
7048            throw new SecurityException("Requires permission "
7049                    + android.Manifest.permission.SHUTDOWN);
7050        }
7051
7052        boolean timedout = false;
7053
7054        synchronized(this) {
7055            mShuttingDown = true;
7056            updateEventDispatchingLocked();
7057
7058            if (mMainStack.mResumedActivity != null) {
7059                mMainStack.stopIfSleepingLocked();
7060                final long endTime = System.currentTimeMillis() + timeout;
7061                while (mMainStack.mResumedActivity != null
7062                        || mMainStack.mPausingActivity != null) {
7063                    long delay = endTime - System.currentTimeMillis();
7064                    if (delay <= 0) {
7065                        Slog.w(TAG, "Activity manager shutdown timed out");
7066                        timedout = true;
7067                        break;
7068                    }
7069                    try {
7070                        this.wait();
7071                    } catch (InterruptedException e) {
7072                    }
7073                }
7074            }
7075        }
7076
7077        mUsageStatsService.shutdown();
7078        mBatteryStatsService.shutdown();
7079
7080        return timedout;
7081    }
7082
7083    public final void activitySlept(IBinder token) {
7084        if (localLOGV) Slog.v(
7085            TAG, "Activity slept: token=" + token);
7086
7087        ActivityRecord r = null;
7088
7089        final long origId = Binder.clearCallingIdentity();
7090
7091        synchronized (this) {
7092            r = mMainStack.isInStackLocked(token);
7093            if (r != null) {
7094                mMainStack.activitySleptLocked(r);
7095            }
7096        }
7097
7098        Binder.restoreCallingIdentity(origId);
7099    }
7100
7101    private void comeOutOfSleepIfNeededLocked() {
7102        if (!mWentToSleep && !mLockScreenShown) {
7103            if (mSleeping) {
7104                mSleeping = false;
7105                mMainStack.awakeFromSleepingLocked();
7106                mMainStack.resumeTopActivityLocked(null);
7107            }
7108        }
7109    }
7110
7111    public void wakingUp() {
7112        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7113                != PackageManager.PERMISSION_GRANTED) {
7114            throw new SecurityException("Requires permission "
7115                    + android.Manifest.permission.DEVICE_POWER);
7116        }
7117
7118        synchronized(this) {
7119            mWentToSleep = false;
7120            updateEventDispatchingLocked();
7121            comeOutOfSleepIfNeededLocked();
7122        }
7123    }
7124
7125    private void updateEventDispatchingLocked() {
7126        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7127    }
7128
7129    public void setLockScreenShown(boolean shown) {
7130        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7131                != PackageManager.PERMISSION_GRANTED) {
7132            throw new SecurityException("Requires permission "
7133                    + android.Manifest.permission.DEVICE_POWER);
7134        }
7135
7136        synchronized(this) {
7137            mLockScreenShown = shown;
7138            comeOutOfSleepIfNeededLocked();
7139        }
7140    }
7141
7142    public void stopAppSwitches() {
7143        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7144                != PackageManager.PERMISSION_GRANTED) {
7145            throw new SecurityException("Requires permission "
7146                    + android.Manifest.permission.STOP_APP_SWITCHES);
7147        }
7148
7149        synchronized(this) {
7150            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7151                    + APP_SWITCH_DELAY_TIME;
7152            mDidAppSwitch = false;
7153            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7154            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7155            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7156        }
7157    }
7158
7159    public void resumeAppSwitches() {
7160        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7161                != PackageManager.PERMISSION_GRANTED) {
7162            throw new SecurityException("Requires permission "
7163                    + android.Manifest.permission.STOP_APP_SWITCHES);
7164        }
7165
7166        synchronized(this) {
7167            // Note that we don't execute any pending app switches... we will
7168            // let those wait until either the timeout, or the next start
7169            // activity request.
7170            mAppSwitchesAllowedTime = 0;
7171        }
7172    }
7173
7174    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7175            String name) {
7176        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7177            return true;
7178        }
7179
7180        final int perm = checkComponentPermission(
7181                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7182                callingUid, -1, true);
7183        if (perm == PackageManager.PERMISSION_GRANTED) {
7184            return true;
7185        }
7186
7187        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7188        return false;
7189    }
7190
7191    public void setDebugApp(String packageName, boolean waitForDebugger,
7192            boolean persistent) {
7193        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7194                "setDebugApp()");
7195
7196        // Note that this is not really thread safe if there are multiple
7197        // callers into it at the same time, but that's not a situation we
7198        // care about.
7199        if (persistent) {
7200            final ContentResolver resolver = mContext.getContentResolver();
7201            Settings.System.putString(
7202                resolver, Settings.System.DEBUG_APP,
7203                packageName);
7204            Settings.System.putInt(
7205                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7206                waitForDebugger ? 1 : 0);
7207        }
7208
7209        synchronized (this) {
7210            if (!persistent) {
7211                mOrigDebugApp = mDebugApp;
7212                mOrigWaitForDebugger = mWaitForDebugger;
7213            }
7214            mDebugApp = packageName;
7215            mWaitForDebugger = waitForDebugger;
7216            mDebugTransient = !persistent;
7217            if (packageName != null) {
7218                final long origId = Binder.clearCallingIdentity();
7219                forceStopPackageLocked(packageName, -1, false, false, true, true,
7220                        UserHandle.USER_ALL);
7221                Binder.restoreCallingIdentity(origId);
7222            }
7223        }
7224    }
7225
7226    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7227        synchronized (this) {
7228            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7229            if (!isDebuggable) {
7230                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7231                    throw new SecurityException("Process not debuggable: " + app.packageName);
7232                }
7233            }
7234
7235            mOpenGlTraceApp = processName;
7236        }
7237    }
7238
7239    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7240            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7241        synchronized (this) {
7242            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7243            if (!isDebuggable) {
7244                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7245                    throw new SecurityException("Process not debuggable: " + app.packageName);
7246                }
7247            }
7248            mProfileApp = processName;
7249            mProfileFile = profileFile;
7250            if (mProfileFd != null) {
7251                try {
7252                    mProfileFd.close();
7253                } catch (IOException e) {
7254                }
7255                mProfileFd = null;
7256            }
7257            mProfileFd = profileFd;
7258            mProfileType = 0;
7259            mAutoStopProfiler = autoStopProfiler;
7260        }
7261    }
7262
7263    public void setAlwaysFinish(boolean enabled) {
7264        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7265                "setAlwaysFinish()");
7266
7267        Settings.System.putInt(
7268                mContext.getContentResolver(),
7269                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7270
7271        synchronized (this) {
7272            mAlwaysFinishActivities = enabled;
7273        }
7274    }
7275
7276    public void setActivityController(IActivityController controller) {
7277        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7278                "setActivityController()");
7279        synchronized (this) {
7280            mController = controller;
7281        }
7282    }
7283
7284    public boolean isUserAMonkey() {
7285        // For now the fact that there is a controller implies
7286        // we have a monkey.
7287        synchronized (this) {
7288            return mController != null;
7289        }
7290    }
7291
7292    public void registerProcessObserver(IProcessObserver observer) {
7293        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7294                "registerProcessObserver()");
7295        synchronized (this) {
7296            mProcessObservers.register(observer);
7297        }
7298    }
7299
7300    public void unregisterProcessObserver(IProcessObserver observer) {
7301        synchronized (this) {
7302            mProcessObservers.unregister(observer);
7303        }
7304    }
7305
7306    public void setImmersive(IBinder token, boolean immersive) {
7307        synchronized(this) {
7308            ActivityRecord r = mMainStack.isInStackLocked(token);
7309            if (r == null) {
7310                throw new IllegalArgumentException();
7311            }
7312            r.immersive = immersive;
7313        }
7314    }
7315
7316    public boolean isImmersive(IBinder token) {
7317        synchronized (this) {
7318            ActivityRecord r = mMainStack.isInStackLocked(token);
7319            if (r == null) {
7320                throw new IllegalArgumentException();
7321            }
7322            return r.immersive;
7323        }
7324    }
7325
7326    public boolean isTopActivityImmersive() {
7327        enforceNotIsolatedCaller("startActivity");
7328        synchronized (this) {
7329            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7330            return (r != null) ? r.immersive : false;
7331        }
7332    }
7333
7334    public final void enterSafeMode() {
7335        synchronized(this) {
7336            // It only makes sense to do this before the system is ready
7337            // and started launching other packages.
7338            if (!mSystemReady) {
7339                try {
7340                    AppGlobals.getPackageManager().enterSafeMode();
7341                } catch (RemoteException e) {
7342                }
7343            }
7344        }
7345    }
7346
7347    public final void showSafeModeOverlay() {
7348        View v = LayoutInflater.from(mContext).inflate(
7349                com.android.internal.R.layout.safe_mode, null);
7350        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7351        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7352        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7353        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7354        lp.gravity = Gravity.BOTTOM | Gravity.START;
7355        lp.format = v.getBackground().getOpacity();
7356        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7357                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7358        ((WindowManager)mContext.getSystemService(
7359                Context.WINDOW_SERVICE)).addView(v, lp);
7360    }
7361
7362    public void noteWakeupAlarm(IIntentSender sender) {
7363        if (!(sender instanceof PendingIntentRecord)) {
7364            return;
7365        }
7366        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7367        synchronized (stats) {
7368            if (mBatteryStatsService.isOnBattery()) {
7369                mBatteryStatsService.enforceCallingPermission();
7370                PendingIntentRecord rec = (PendingIntentRecord)sender;
7371                int MY_UID = Binder.getCallingUid();
7372                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7373                BatteryStatsImpl.Uid.Pkg pkg =
7374                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7375                pkg.incWakeupsLocked();
7376            }
7377        }
7378    }
7379
7380    public boolean killPids(int[] pids, String pReason, boolean secure) {
7381        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7382            throw new SecurityException("killPids only available to the system");
7383        }
7384        String reason = (pReason == null) ? "Unknown" : pReason;
7385        // XXX Note: don't acquire main activity lock here, because the window
7386        // manager calls in with its locks held.
7387
7388        boolean killed = false;
7389        synchronized (mPidsSelfLocked) {
7390            int[] types = new int[pids.length];
7391            int worstType = 0;
7392            for (int i=0; i<pids.length; i++) {
7393                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7394                if (proc != null) {
7395                    int type = proc.setAdj;
7396                    types[i] = type;
7397                    if (type > worstType) {
7398                        worstType = type;
7399                    }
7400                }
7401            }
7402
7403            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7404            // then constrain it so we will kill all hidden procs.
7405            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7406                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7407                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7408            }
7409
7410            // If this is not a secure call, don't let it kill processes that
7411            // are important.
7412            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7413                worstType = ProcessList.SERVICE_ADJ;
7414            }
7415
7416            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7417            for (int i=0; i<pids.length; i++) {
7418                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7419                if (proc == null) {
7420                    continue;
7421                }
7422                int adj = proc.setAdj;
7423                if (adj >= worstType && !proc.killedBackground) {
7424                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7425                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7426                            proc.processName, adj, reason);
7427                    killed = true;
7428                    proc.killedBackground = true;
7429                    Process.killProcessQuiet(pids[i]);
7430                }
7431            }
7432        }
7433        return killed;
7434    }
7435
7436    @Override
7437    public boolean killProcessesBelowForeground(String reason) {
7438        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7439            throw new SecurityException("killProcessesBelowForeground() only available to system");
7440        }
7441
7442        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7443    }
7444
7445    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7446        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7447            throw new SecurityException("killProcessesBelowAdj() only available to system");
7448        }
7449
7450        boolean killed = false;
7451        synchronized (mPidsSelfLocked) {
7452            final int size = mPidsSelfLocked.size();
7453            for (int i = 0; i < size; i++) {
7454                final int pid = mPidsSelfLocked.keyAt(i);
7455                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7456                if (proc == null) continue;
7457
7458                final int adj = proc.setAdj;
7459                if (adj > belowAdj && !proc.killedBackground) {
7460                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7461                    EventLog.writeEvent(
7462                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7463                    killed = true;
7464                    proc.killedBackground = true;
7465                    Process.killProcessQuiet(pid);
7466                }
7467            }
7468        }
7469        return killed;
7470    }
7471
7472    public final void startRunning(String pkg, String cls, String action,
7473            String data) {
7474        synchronized(this) {
7475            if (mStartRunning) {
7476                return;
7477            }
7478            mStartRunning = true;
7479            mTopComponent = pkg != null && cls != null
7480                    ? new ComponentName(pkg, cls) : null;
7481            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7482            mTopData = data;
7483            if (!mSystemReady) {
7484                return;
7485            }
7486        }
7487
7488        systemReady(null);
7489    }
7490
7491    private void retrieveSettings() {
7492        final ContentResolver resolver = mContext.getContentResolver();
7493        String debugApp = Settings.System.getString(
7494            resolver, Settings.System.DEBUG_APP);
7495        boolean waitForDebugger = Settings.System.getInt(
7496            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7497        boolean alwaysFinishActivities = Settings.System.getInt(
7498            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7499
7500        Configuration configuration = new Configuration();
7501        Settings.System.getConfiguration(resolver, configuration);
7502
7503        synchronized (this) {
7504            mDebugApp = mOrigDebugApp = debugApp;
7505            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7506            mAlwaysFinishActivities = alwaysFinishActivities;
7507            // This happens before any activities are started, so we can
7508            // change mConfiguration in-place.
7509            updateConfigurationLocked(configuration, null, false, true);
7510            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7511        }
7512    }
7513
7514    public boolean testIsSystemReady() {
7515        // no need to synchronize(this) just to read & return the value
7516        return mSystemReady;
7517    }
7518
7519    private static File getCalledPreBootReceiversFile() {
7520        File dataDir = Environment.getDataDirectory();
7521        File systemDir = new File(dataDir, "system");
7522        File fname = new File(systemDir, "called_pre_boots.dat");
7523        return fname;
7524    }
7525
7526    static final int LAST_DONE_VERSION = 10000;
7527
7528    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7529        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7530        File file = getCalledPreBootReceiversFile();
7531        FileInputStream fis = null;
7532        try {
7533            fis = new FileInputStream(file);
7534            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7535            int fvers = dis.readInt();
7536            if (fvers == LAST_DONE_VERSION) {
7537                String vers = dis.readUTF();
7538                String codename = dis.readUTF();
7539                String build = dis.readUTF();
7540                if (android.os.Build.VERSION.RELEASE.equals(vers)
7541                        && android.os.Build.VERSION.CODENAME.equals(codename)
7542                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7543                    int num = dis.readInt();
7544                    while (num > 0) {
7545                        num--;
7546                        String pkg = dis.readUTF();
7547                        String cls = dis.readUTF();
7548                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7549                    }
7550                }
7551            }
7552        } catch (FileNotFoundException e) {
7553        } catch (IOException e) {
7554            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7555        } finally {
7556            if (fis != null) {
7557                try {
7558                    fis.close();
7559                } catch (IOException e) {
7560                }
7561            }
7562        }
7563        return lastDoneReceivers;
7564    }
7565
7566    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7567        File file = getCalledPreBootReceiversFile();
7568        FileOutputStream fos = null;
7569        DataOutputStream dos = null;
7570        try {
7571            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7572            fos = new FileOutputStream(file);
7573            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7574            dos.writeInt(LAST_DONE_VERSION);
7575            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7576            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7577            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7578            dos.writeInt(list.size());
7579            for (int i=0; i<list.size(); i++) {
7580                dos.writeUTF(list.get(i).getPackageName());
7581                dos.writeUTF(list.get(i).getClassName());
7582            }
7583        } catch (IOException e) {
7584            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7585            file.delete();
7586        } finally {
7587            FileUtils.sync(fos);
7588            if (dos != null) {
7589                try {
7590                    dos.close();
7591                } catch (IOException e) {
7592                    // TODO Auto-generated catch block
7593                    e.printStackTrace();
7594                }
7595            }
7596        }
7597    }
7598
7599    public void systemReady(final Runnable goingCallback) {
7600        synchronized(this) {
7601            if (mSystemReady) {
7602                if (goingCallback != null) goingCallback.run();
7603                return;
7604            }
7605
7606            // Check to see if there are any update receivers to run.
7607            if (!mDidUpdate) {
7608                if (mWaitingUpdate) {
7609                    return;
7610                }
7611                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7612                List<ResolveInfo> ris = null;
7613                try {
7614                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7615                            intent, null, 0, 0);
7616                } catch (RemoteException e) {
7617                }
7618                if (ris != null) {
7619                    for (int i=ris.size()-1; i>=0; i--) {
7620                        if ((ris.get(i).activityInfo.applicationInfo.flags
7621                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7622                            ris.remove(i);
7623                        }
7624                    }
7625                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7626
7627                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7628
7629                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7630                    for (int i=0; i<ris.size(); i++) {
7631                        ActivityInfo ai = ris.get(i).activityInfo;
7632                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7633                        if (lastDoneReceivers.contains(comp)) {
7634                            ris.remove(i);
7635                            i--;
7636                        }
7637                    }
7638
7639                    for (int i=0; i<ris.size(); i++) {
7640                        ActivityInfo ai = ris.get(i).activityInfo;
7641                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7642                        doneReceivers.add(comp);
7643                        intent.setComponent(comp);
7644                        IIntentReceiver finisher = null;
7645                        if (i == ris.size()-1) {
7646                            finisher = new IIntentReceiver.Stub() {
7647                                public void performReceive(Intent intent, int resultCode,
7648                                        String data, Bundle extras, boolean ordered,
7649                                        boolean sticky, int sendingUser) {
7650                                    // The raw IIntentReceiver interface is called
7651                                    // with the AM lock held, so redispatch to
7652                                    // execute our code without the lock.
7653                                    mHandler.post(new Runnable() {
7654                                        public void run() {
7655                                            synchronized (ActivityManagerService.this) {
7656                                                mDidUpdate = true;
7657                                            }
7658                                            writeLastDonePreBootReceivers(doneReceivers);
7659                                            showBootMessage(mContext.getText(
7660                                                    R.string.android_upgrading_complete),
7661                                                    false);
7662                                            systemReady(goingCallback);
7663                                        }
7664                                    });
7665                                }
7666                            };
7667                        }
7668                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7669                        // XXX also need to send this to stopped users(!!!)
7670                        broadcastIntentLocked(null, null, intent, null, finisher,
7671                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7672                                UserHandle.USER_ALL);
7673                        if (finisher != null) {
7674                            mWaitingUpdate = true;
7675                        }
7676                    }
7677                }
7678                if (mWaitingUpdate) {
7679                    return;
7680                }
7681                mDidUpdate = true;
7682            }
7683
7684            mSystemReady = true;
7685            if (!mStartRunning) {
7686                return;
7687            }
7688        }
7689
7690        ArrayList<ProcessRecord> procsToKill = null;
7691        synchronized(mPidsSelfLocked) {
7692            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7693                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7694                if (!isAllowedWhileBooting(proc.info)){
7695                    if (procsToKill == null) {
7696                        procsToKill = new ArrayList<ProcessRecord>();
7697                    }
7698                    procsToKill.add(proc);
7699                }
7700            }
7701        }
7702
7703        synchronized(this) {
7704            if (procsToKill != null) {
7705                for (int i=procsToKill.size()-1; i>=0; i--) {
7706                    ProcessRecord proc = procsToKill.get(i);
7707                    Slog.i(TAG, "Removing system update proc: " + proc);
7708                    removeProcessLocked(proc, true, false, "system update done");
7709                }
7710            }
7711
7712            // Now that we have cleaned up any update processes, we
7713            // are ready to start launching real processes and know that
7714            // we won't trample on them any more.
7715            mProcessesReady = true;
7716        }
7717
7718        Slog.i(TAG, "System now ready");
7719        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7720            SystemClock.uptimeMillis());
7721
7722        synchronized(this) {
7723            // Make sure we have no pre-ready processes sitting around.
7724
7725            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7726                ResolveInfo ri = mContext.getPackageManager()
7727                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7728                                STOCK_PM_FLAGS);
7729                CharSequence errorMsg = null;
7730                if (ri != null) {
7731                    ActivityInfo ai = ri.activityInfo;
7732                    ApplicationInfo app = ai.applicationInfo;
7733                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7734                        mTopAction = Intent.ACTION_FACTORY_TEST;
7735                        mTopData = null;
7736                        mTopComponent = new ComponentName(app.packageName,
7737                                ai.name);
7738                    } else {
7739                        errorMsg = mContext.getResources().getText(
7740                                com.android.internal.R.string.factorytest_not_system);
7741                    }
7742                } else {
7743                    errorMsg = mContext.getResources().getText(
7744                            com.android.internal.R.string.factorytest_no_action);
7745                }
7746                if (errorMsg != null) {
7747                    mTopAction = null;
7748                    mTopData = null;
7749                    mTopComponent = null;
7750                    Message msg = Message.obtain();
7751                    msg.what = SHOW_FACTORY_ERROR_MSG;
7752                    msg.getData().putCharSequence("msg", errorMsg);
7753                    mHandler.sendMessage(msg);
7754                }
7755            }
7756        }
7757
7758        retrieveSettings();
7759
7760        if (goingCallback != null) goingCallback.run();
7761
7762        synchronized (this) {
7763            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7764                try {
7765                    List apps = AppGlobals.getPackageManager().
7766                        getPersistentApplications(STOCK_PM_FLAGS);
7767                    if (apps != null) {
7768                        int N = apps.size();
7769                        int i;
7770                        for (i=0; i<N; i++) {
7771                            ApplicationInfo info
7772                                = (ApplicationInfo)apps.get(i);
7773                            if (info != null &&
7774                                    !info.packageName.equals("android")) {
7775                                addAppLocked(info, false);
7776                            }
7777                        }
7778                    }
7779                } catch (RemoteException ex) {
7780                    // pm is in same process, this will never happen.
7781                }
7782            }
7783
7784            // Start up initial activity.
7785            mBooting = true;
7786
7787            try {
7788                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7789                    Message msg = Message.obtain();
7790                    msg.what = SHOW_UID_ERROR_MSG;
7791                    mHandler.sendMessage(msg);
7792                }
7793            } catch (RemoteException e) {
7794            }
7795
7796            mMainStack.resumeTopActivityLocked(null);
7797        }
7798    }
7799
7800    private boolean makeAppCrashingLocked(ProcessRecord app,
7801            String shortMsg, String longMsg, String stackTrace) {
7802        app.crashing = true;
7803        app.crashingReport = generateProcessError(app,
7804                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7805        startAppProblemLocked(app);
7806        app.stopFreezingAllLocked();
7807        return handleAppCrashLocked(app);
7808    }
7809
7810    private void makeAppNotRespondingLocked(ProcessRecord app,
7811            String activity, String shortMsg, String longMsg) {
7812        app.notResponding = true;
7813        app.notRespondingReport = generateProcessError(app,
7814                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7815                activity, shortMsg, longMsg, null);
7816        startAppProblemLocked(app);
7817        app.stopFreezingAllLocked();
7818    }
7819
7820    /**
7821     * Generate a process error record, suitable for attachment to a ProcessRecord.
7822     *
7823     * @param app The ProcessRecord in which the error occurred.
7824     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7825     *                      ActivityManager.AppErrorStateInfo
7826     * @param activity The activity associated with the crash, if known.
7827     * @param shortMsg Short message describing the crash.
7828     * @param longMsg Long message describing the crash.
7829     * @param stackTrace Full crash stack trace, may be null.
7830     *
7831     * @return Returns a fully-formed AppErrorStateInfo record.
7832     */
7833    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7834            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7835        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7836
7837        report.condition = condition;
7838        report.processName = app.processName;
7839        report.pid = app.pid;
7840        report.uid = app.info.uid;
7841        report.tag = activity;
7842        report.shortMsg = shortMsg;
7843        report.longMsg = longMsg;
7844        report.stackTrace = stackTrace;
7845
7846        return report;
7847    }
7848
7849    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7850        synchronized (this) {
7851            app.crashing = false;
7852            app.crashingReport = null;
7853            app.notResponding = false;
7854            app.notRespondingReport = null;
7855            if (app.anrDialog == fromDialog) {
7856                app.anrDialog = null;
7857            }
7858            if (app.waitDialog == fromDialog) {
7859                app.waitDialog = null;
7860            }
7861            if (app.pid > 0 && app.pid != MY_PID) {
7862                handleAppCrashLocked(app);
7863                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7864                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7865                        app.processName, app.setAdj, "user's request after error");
7866                Process.killProcessQuiet(app.pid);
7867            }
7868        }
7869    }
7870
7871    private boolean handleAppCrashLocked(ProcessRecord app) {
7872        if (mHeadless) {
7873            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7874            return false;
7875        }
7876        long now = SystemClock.uptimeMillis();
7877
7878        Long crashTime;
7879        if (!app.isolated) {
7880            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7881        } else {
7882            crashTime = null;
7883        }
7884        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7885            // This process loses!
7886            Slog.w(TAG, "Process " + app.info.processName
7887                    + " has crashed too many times: killing!");
7888            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7889                    app.info.processName, app.uid);
7890            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7891                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7892                if (r.app == app) {
7893                    Slog.w(TAG, "  Force finishing activity "
7894                        + r.intent.getComponent().flattenToShortString());
7895                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
7896                            null, "crashed", false);
7897                }
7898            }
7899            if (!app.persistent) {
7900                // We don't want to start this process again until the user
7901                // explicitly does so...  but for persistent process, we really
7902                // need to keep it running.  If a persistent process is actually
7903                // repeatedly crashing, then badness for everyone.
7904                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7905                        app.info.processName);
7906                if (!app.isolated) {
7907                    // XXX We don't have a way to mark isolated processes
7908                    // as bad, since they don't have a peristent identity.
7909                    mBadProcesses.put(app.info.processName, app.uid, now);
7910                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7911                }
7912                app.bad = true;
7913                app.removed = true;
7914                // Don't let services in this process be restarted and potentially
7915                // annoy the user repeatedly.  Unless it is persistent, since those
7916                // processes run critical code.
7917                removeProcessLocked(app, false, false, "crash");
7918                mMainStack.resumeTopActivityLocked(null);
7919                return false;
7920            }
7921            mMainStack.resumeTopActivityLocked(null);
7922        } else {
7923            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7924            if (r != null && r.app == app) {
7925                // If the top running activity is from this crashing
7926                // process, then terminate it to avoid getting in a loop.
7927                Slog.w(TAG, "  Force finishing activity "
7928                        + r.intent.getComponent().flattenToShortString());
7929                int index = mMainStack.indexOfActivityLocked(r);
7930                r.stack.finishActivityLocked(r, index,
7931                        Activity.RESULT_CANCELED, null, "crashed", false);
7932                // Also terminate any activities below it that aren't yet
7933                // stopped, to avoid a situation where one will get
7934                // re-start our crashing activity once it gets resumed again.
7935                index--;
7936                if (index >= 0) {
7937                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7938                    if (r.state == ActivityState.RESUMED
7939                            || r.state == ActivityState.PAUSING
7940                            || r.state == ActivityState.PAUSED) {
7941                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7942                            Slog.w(TAG, "  Force finishing activity "
7943                                    + r.intent.getComponent().flattenToShortString());
7944                            r.stack.finishActivityLocked(r, index,
7945                                    Activity.RESULT_CANCELED, null, "crashed", false);
7946                        }
7947                    }
7948                }
7949            }
7950        }
7951
7952        // Bump up the crash count of any services currently running in the proc.
7953        if (app.services.size() != 0) {
7954            // Any services running in the application need to be placed
7955            // back in the pending list.
7956            Iterator<ServiceRecord> it = app.services.iterator();
7957            while (it.hasNext()) {
7958                ServiceRecord sr = it.next();
7959                sr.crashCount++;
7960            }
7961        }
7962
7963        // If the crashing process is what we consider to be the "home process" and it has been
7964        // replaced by a third-party app, clear the package preferred activities from packages
7965        // with a home activity running in the process to prevent a repeatedly crashing app
7966        // from blocking the user to manually clear the list.
7967        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7968                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7969            Iterator it = mHomeProcess.activities.iterator();
7970            while (it.hasNext()) {
7971                ActivityRecord r = (ActivityRecord)it.next();
7972                if (r.isHomeActivity) {
7973                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7974                    try {
7975                        ActivityThread.getPackageManager()
7976                                .clearPackagePreferredActivities(r.packageName);
7977                    } catch (RemoteException c) {
7978                        // pm is in same process, this will never happen.
7979                    }
7980                }
7981            }
7982        }
7983
7984        if (!app.isolated) {
7985            // XXX Can't keep track of crash times for isolated processes,
7986            // because they don't have a perisistent identity.
7987            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7988        }
7989
7990        return true;
7991    }
7992
7993    void startAppProblemLocked(ProcessRecord app) {
7994        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7995                mContext, app.info.packageName, app.info.flags);
7996        skipCurrentReceiverLocked(app);
7997    }
7998
7999    void skipCurrentReceiverLocked(ProcessRecord app) {
8000        for (BroadcastQueue queue : mBroadcastQueues) {
8001            queue.skipCurrentReceiverLocked(app);
8002        }
8003    }
8004
8005    /**
8006     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8007     * The application process will exit immediately after this call returns.
8008     * @param app object of the crashing app, null for the system server
8009     * @param crashInfo describing the exception
8010     */
8011    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8012        ProcessRecord r = findAppProcess(app, "Crash");
8013        final String processName = app == null ? "system_server"
8014                : (r == null ? "unknown" : r.processName);
8015
8016        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8017                processName,
8018                r == null ? -1 : r.info.flags,
8019                crashInfo.exceptionClassName,
8020                crashInfo.exceptionMessage,
8021                crashInfo.throwFileName,
8022                crashInfo.throwLineNumber);
8023
8024        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
8025
8026        crashApplication(r, crashInfo);
8027    }
8028
8029    public void handleApplicationStrictModeViolation(
8030            IBinder app,
8031            int violationMask,
8032            StrictMode.ViolationInfo info) {
8033        ProcessRecord r = findAppProcess(app, "StrictMode");
8034        if (r == null) {
8035            return;
8036        }
8037
8038        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
8039            Integer stackFingerprint = info.hashCode();
8040            boolean logIt = true;
8041            synchronized (mAlreadyLoggedViolatedStacks) {
8042                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8043                    logIt = false;
8044                    // TODO: sub-sample into EventLog for these, with
8045                    // the info.durationMillis?  Then we'd get
8046                    // the relative pain numbers, without logging all
8047                    // the stack traces repeatedly.  We'd want to do
8048                    // likewise in the client code, which also does
8049                    // dup suppression, before the Binder call.
8050                } else {
8051                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8052                        mAlreadyLoggedViolatedStacks.clear();
8053                    }
8054                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8055                }
8056            }
8057            if (logIt) {
8058                logStrictModeViolationToDropBox(r, info);
8059            }
8060        }
8061
8062        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8063            AppErrorResult result = new AppErrorResult();
8064            synchronized (this) {
8065                final long origId = Binder.clearCallingIdentity();
8066
8067                Message msg = Message.obtain();
8068                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8069                HashMap<String, Object> data = new HashMap<String, Object>();
8070                data.put("result", result);
8071                data.put("app", r);
8072                data.put("violationMask", violationMask);
8073                data.put("info", info);
8074                msg.obj = data;
8075                mHandler.sendMessage(msg);
8076
8077                Binder.restoreCallingIdentity(origId);
8078            }
8079            int res = result.get();
8080            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8081        }
8082    }
8083
8084    // Depending on the policy in effect, there could be a bunch of
8085    // these in quick succession so we try to batch these together to
8086    // minimize disk writes, number of dropbox entries, and maximize
8087    // compression, by having more fewer, larger records.
8088    private void logStrictModeViolationToDropBox(
8089            ProcessRecord process,
8090            StrictMode.ViolationInfo info) {
8091        if (info == null) {
8092            return;
8093        }
8094        final boolean isSystemApp = process == null ||
8095                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8096                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8097        final String processName = process == null ? "unknown" : process.processName;
8098        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8099        final DropBoxManager dbox = (DropBoxManager)
8100                mContext.getSystemService(Context.DROPBOX_SERVICE);
8101
8102        // Exit early if the dropbox isn't configured to accept this report type.
8103        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8104
8105        boolean bufferWasEmpty;
8106        boolean needsFlush;
8107        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8108        synchronized (sb) {
8109            bufferWasEmpty = sb.length() == 0;
8110            appendDropBoxProcessHeaders(process, processName, sb);
8111            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8112            sb.append("System-App: ").append(isSystemApp).append("\n");
8113            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8114            if (info.violationNumThisLoop != 0) {
8115                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8116            }
8117            if (info.numAnimationsRunning != 0) {
8118                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8119            }
8120            if (info.broadcastIntentAction != null) {
8121                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8122            }
8123            if (info.durationMillis != -1) {
8124                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8125            }
8126            if (info.numInstances != -1) {
8127                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8128            }
8129            if (info.tags != null) {
8130                for (String tag : info.tags) {
8131                    sb.append("Span-Tag: ").append(tag).append("\n");
8132                }
8133            }
8134            sb.append("\n");
8135            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8136                sb.append(info.crashInfo.stackTrace);
8137            }
8138            sb.append("\n");
8139
8140            // Only buffer up to ~64k.  Various logging bits truncate
8141            // things at 128k.
8142            needsFlush = (sb.length() > 64 * 1024);
8143        }
8144
8145        // Flush immediately if the buffer's grown too large, or this
8146        // is a non-system app.  Non-system apps are isolated with a
8147        // different tag & policy and not batched.
8148        //
8149        // Batching is useful during internal testing with
8150        // StrictMode settings turned up high.  Without batching,
8151        // thousands of separate files could be created on boot.
8152        if (!isSystemApp || needsFlush) {
8153            new Thread("Error dump: " + dropboxTag) {
8154                @Override
8155                public void run() {
8156                    String report;
8157                    synchronized (sb) {
8158                        report = sb.toString();
8159                        sb.delete(0, sb.length());
8160                        sb.trimToSize();
8161                    }
8162                    if (report.length() != 0) {
8163                        dbox.addText(dropboxTag, report);
8164                    }
8165                }
8166            }.start();
8167            return;
8168        }
8169
8170        // System app batching:
8171        if (!bufferWasEmpty) {
8172            // An existing dropbox-writing thread is outstanding, so
8173            // we don't need to start it up.  The existing thread will
8174            // catch the buffer appends we just did.
8175            return;
8176        }
8177
8178        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8179        // (After this point, we shouldn't access AMS internal data structures.)
8180        new Thread("Error dump: " + dropboxTag) {
8181            @Override
8182            public void run() {
8183                // 5 second sleep to let stacks arrive and be batched together
8184                try {
8185                    Thread.sleep(5000);  // 5 seconds
8186                } catch (InterruptedException e) {}
8187
8188                String errorReport;
8189                synchronized (mStrictModeBuffer) {
8190                    errorReport = mStrictModeBuffer.toString();
8191                    if (errorReport.length() == 0) {
8192                        return;
8193                    }
8194                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8195                    mStrictModeBuffer.trimToSize();
8196                }
8197                dbox.addText(dropboxTag, errorReport);
8198            }
8199        }.start();
8200    }
8201
8202    /**
8203     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8204     * @param app object of the crashing app, null for the system server
8205     * @param tag reported by the caller
8206     * @param crashInfo describing the context of the error
8207     * @return true if the process should exit immediately (WTF is fatal)
8208     */
8209    public boolean handleApplicationWtf(IBinder app, String tag,
8210            ApplicationErrorReport.CrashInfo crashInfo) {
8211        ProcessRecord r = findAppProcess(app, "WTF");
8212        final String processName = app == null ? "system_server"
8213                : (r == null ? "unknown" : r.processName);
8214
8215        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8216                processName,
8217                r == null ? -1 : r.info.flags,
8218                tag, crashInfo.exceptionMessage);
8219
8220        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8221
8222        if (r != null && r.pid != Process.myPid() &&
8223                Settings.Secure.getInt(mContext.getContentResolver(),
8224                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8225            crashApplication(r, crashInfo);
8226            return true;
8227        } else {
8228            return false;
8229        }
8230    }
8231
8232    /**
8233     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8234     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8235     */
8236    private ProcessRecord findAppProcess(IBinder app, String reason) {
8237        if (app == null) {
8238            return null;
8239        }
8240
8241        synchronized (this) {
8242            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8243                final int NA = apps.size();
8244                for (int ia=0; ia<NA; ia++) {
8245                    ProcessRecord p = apps.valueAt(ia);
8246                    if (p.thread != null && p.thread.asBinder() == app) {
8247                        return p;
8248                    }
8249                }
8250            }
8251
8252            Slog.w(TAG, "Can't find mystery application for " + reason
8253                    + " from pid=" + Binder.getCallingPid()
8254                    + " uid=" + Binder.getCallingUid() + ": " + app);
8255            return null;
8256        }
8257    }
8258
8259    /**
8260     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8261     * to append various headers to the dropbox log text.
8262     */
8263    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8264            StringBuilder sb) {
8265        // Watchdog thread ends up invoking this function (with
8266        // a null ProcessRecord) to add the stack file to dropbox.
8267        // Do not acquire a lock on this (am) in such cases, as it
8268        // could cause a potential deadlock, if and when watchdog
8269        // is invoked due to unavailability of lock on am and it
8270        // would prevent watchdog from killing system_server.
8271        if (process == null) {
8272            sb.append("Process: ").append(processName).append("\n");
8273            return;
8274        }
8275        // Note: ProcessRecord 'process' is guarded by the service
8276        // instance.  (notably process.pkgList, which could otherwise change
8277        // concurrently during execution of this method)
8278        synchronized (this) {
8279            sb.append("Process: ").append(processName).append("\n");
8280            int flags = process.info.flags;
8281            IPackageManager pm = AppGlobals.getPackageManager();
8282            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8283            for (String pkg : process.pkgList) {
8284                sb.append("Package: ").append(pkg);
8285                try {
8286                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8287                    if (pi != null) {
8288                        sb.append(" v").append(pi.versionCode);
8289                        if (pi.versionName != null) {
8290                            sb.append(" (").append(pi.versionName).append(")");
8291                        }
8292                    }
8293                } catch (RemoteException e) {
8294                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8295                }
8296                sb.append("\n");
8297            }
8298        }
8299    }
8300
8301    private static String processClass(ProcessRecord process) {
8302        if (process == null || process.pid == MY_PID) {
8303            return "system_server";
8304        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8305            return "system_app";
8306        } else {
8307            return "data_app";
8308        }
8309    }
8310
8311    /**
8312     * Write a description of an error (crash, WTF, ANR) to the drop box.
8313     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8314     * @param process which caused the error, null means the system server
8315     * @param activity which triggered the error, null if unknown
8316     * @param parent activity related to the error, null if unknown
8317     * @param subject line related to the error, null if absent
8318     * @param report in long form describing the error, null if absent
8319     * @param logFile to include in the report, null if none
8320     * @param crashInfo giving an application stack trace, null if absent
8321     */
8322    public void addErrorToDropBox(String eventType,
8323            ProcessRecord process, String processName, ActivityRecord activity,
8324            ActivityRecord parent, String subject,
8325            final String report, final File logFile,
8326            final ApplicationErrorReport.CrashInfo crashInfo) {
8327        // NOTE -- this must never acquire the ActivityManagerService lock,
8328        // otherwise the watchdog may be prevented from resetting the system.
8329
8330        final String dropboxTag = processClass(process) + "_" + eventType;
8331        final DropBoxManager dbox = (DropBoxManager)
8332                mContext.getSystemService(Context.DROPBOX_SERVICE);
8333
8334        // Exit early if the dropbox isn't configured to accept this report type.
8335        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8336
8337        final StringBuilder sb = new StringBuilder(1024);
8338        appendDropBoxProcessHeaders(process, processName, sb);
8339        if (activity != null) {
8340            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8341        }
8342        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8343            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8344        }
8345        if (parent != null && parent != activity) {
8346            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8347        }
8348        if (subject != null) {
8349            sb.append("Subject: ").append(subject).append("\n");
8350        }
8351        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8352        if (Debug.isDebuggerConnected()) {
8353            sb.append("Debugger: Connected\n");
8354        }
8355        sb.append("\n");
8356
8357        // Do the rest in a worker thread to avoid blocking the caller on I/O
8358        // (After this point, we shouldn't access AMS internal data structures.)
8359        Thread worker = new Thread("Error dump: " + dropboxTag) {
8360            @Override
8361            public void run() {
8362                if (report != null) {
8363                    sb.append(report);
8364                }
8365                if (logFile != null) {
8366                    try {
8367                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8368                    } catch (IOException e) {
8369                        Slog.e(TAG, "Error reading " + logFile, e);
8370                    }
8371                }
8372                if (crashInfo != null && crashInfo.stackTrace != null) {
8373                    sb.append(crashInfo.stackTrace);
8374                }
8375
8376                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8377                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8378                if (lines > 0) {
8379                    sb.append("\n");
8380
8381                    // Merge several logcat streams, and take the last N lines
8382                    InputStreamReader input = null;
8383                    try {
8384                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8385                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8386                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8387
8388                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8389                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8390                        input = new InputStreamReader(logcat.getInputStream());
8391
8392                        int num;
8393                        char[] buf = new char[8192];
8394                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8395                    } catch (IOException e) {
8396                        Slog.e(TAG, "Error running logcat", e);
8397                    } finally {
8398                        if (input != null) try { input.close(); } catch (IOException e) {}
8399                    }
8400                }
8401
8402                dbox.addText(dropboxTag, sb.toString());
8403            }
8404        };
8405
8406        if (process == null) {
8407            // If process is null, we are being called from some internal code
8408            // and may be about to die -- run this synchronously.
8409            worker.run();
8410        } else {
8411            worker.start();
8412        }
8413    }
8414
8415    /**
8416     * Bring up the "unexpected error" dialog box for a crashing app.
8417     * Deal with edge cases (intercepts from instrumented applications,
8418     * ActivityController, error intent receivers, that sort of thing).
8419     * @param r the application crashing
8420     * @param crashInfo describing the failure
8421     */
8422    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8423        long timeMillis = System.currentTimeMillis();
8424        String shortMsg = crashInfo.exceptionClassName;
8425        String longMsg = crashInfo.exceptionMessage;
8426        String stackTrace = crashInfo.stackTrace;
8427        if (shortMsg != null && longMsg != null) {
8428            longMsg = shortMsg + ": " + longMsg;
8429        } else if (shortMsg != null) {
8430            longMsg = shortMsg;
8431        }
8432
8433        AppErrorResult result = new AppErrorResult();
8434        synchronized (this) {
8435            if (mController != null) {
8436                try {
8437                    String name = r != null ? r.processName : null;
8438                    int pid = r != null ? r.pid : Binder.getCallingPid();
8439                    if (!mController.appCrashed(name, pid,
8440                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8441                        Slog.w(TAG, "Force-killing crashed app " + name
8442                                + " at watcher's request");
8443                        Process.killProcess(pid);
8444                        return;
8445                    }
8446                } catch (RemoteException e) {
8447                    mController = null;
8448                }
8449            }
8450
8451            final long origId = Binder.clearCallingIdentity();
8452
8453            // If this process is running instrumentation, finish it.
8454            if (r != null && r.instrumentationClass != null) {
8455                Slog.w(TAG, "Error in app " + r.processName
8456                      + " running instrumentation " + r.instrumentationClass + ":");
8457                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8458                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8459                Bundle info = new Bundle();
8460                info.putString("shortMsg", shortMsg);
8461                info.putString("longMsg", longMsg);
8462                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8463                Binder.restoreCallingIdentity(origId);
8464                return;
8465            }
8466
8467            // If we can't identify the process or it's already exceeded its crash quota,
8468            // quit right away without showing a crash dialog.
8469            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8470                Binder.restoreCallingIdentity(origId);
8471                return;
8472            }
8473
8474            Message msg = Message.obtain();
8475            msg.what = SHOW_ERROR_MSG;
8476            HashMap data = new HashMap();
8477            data.put("result", result);
8478            data.put("app", r);
8479            msg.obj = data;
8480            mHandler.sendMessage(msg);
8481
8482            Binder.restoreCallingIdentity(origId);
8483        }
8484
8485        int res = result.get();
8486
8487        Intent appErrorIntent = null;
8488        synchronized (this) {
8489            if (r != null && !r.isolated) {
8490                // XXX Can't keep track of crash time for isolated processes,
8491                // since they don't have a persistent identity.
8492                mProcessCrashTimes.put(r.info.processName, r.uid,
8493                        SystemClock.uptimeMillis());
8494            }
8495            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8496                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8497            }
8498        }
8499
8500        if (appErrorIntent != null) {
8501            try {
8502                mContext.startActivity(appErrorIntent);
8503            } catch (ActivityNotFoundException e) {
8504                Slog.w(TAG, "bug report receiver dissappeared", e);
8505            }
8506        }
8507    }
8508
8509    Intent createAppErrorIntentLocked(ProcessRecord r,
8510            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8511        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8512        if (report == null) {
8513            return null;
8514        }
8515        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8516        result.setComponent(r.errorReportReceiver);
8517        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8518        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8519        return result;
8520    }
8521
8522    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8523            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8524        if (r.errorReportReceiver == null) {
8525            return null;
8526        }
8527
8528        if (!r.crashing && !r.notResponding) {
8529            return null;
8530        }
8531
8532        ApplicationErrorReport report = new ApplicationErrorReport();
8533        report.packageName = r.info.packageName;
8534        report.installerPackageName = r.errorReportReceiver.getPackageName();
8535        report.processName = r.processName;
8536        report.time = timeMillis;
8537        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8538
8539        if (r.crashing) {
8540            report.type = ApplicationErrorReport.TYPE_CRASH;
8541            report.crashInfo = crashInfo;
8542        } else if (r.notResponding) {
8543            report.type = ApplicationErrorReport.TYPE_ANR;
8544            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8545
8546            report.anrInfo.activity = r.notRespondingReport.tag;
8547            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8548            report.anrInfo.info = r.notRespondingReport.longMsg;
8549        }
8550
8551        return report;
8552    }
8553
8554    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8555        enforceNotIsolatedCaller("getProcessesInErrorState");
8556        // assume our apps are happy - lazy create the list
8557        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8558
8559        final boolean allUsers = ActivityManager.checkUidPermission(
8560                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8561                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8562        int userId = UserHandle.getUserId(Binder.getCallingUid());
8563
8564        synchronized (this) {
8565
8566            // iterate across all processes
8567            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8568                ProcessRecord app = mLruProcesses.get(i);
8569                if (!allUsers && app.userId != userId) {
8570                    continue;
8571                }
8572                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8573                    // This one's in trouble, so we'll generate a report for it
8574                    // crashes are higher priority (in case there's a crash *and* an anr)
8575                    ActivityManager.ProcessErrorStateInfo report = null;
8576                    if (app.crashing) {
8577                        report = app.crashingReport;
8578                    } else if (app.notResponding) {
8579                        report = app.notRespondingReport;
8580                    }
8581
8582                    if (report != null) {
8583                        if (errList == null) {
8584                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8585                        }
8586                        errList.add(report);
8587                    } else {
8588                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8589                                " crashing = " + app.crashing +
8590                                " notResponding = " + app.notResponding);
8591                    }
8592                }
8593            }
8594        }
8595
8596        return errList;
8597    }
8598
8599    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8600        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8601            if (currApp != null) {
8602                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8603            }
8604            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8605        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8606            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8607        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8608            if (currApp != null) {
8609                currApp.lru = 0;
8610            }
8611            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8612        } else if (adj >= ProcessList.SERVICE_ADJ) {
8613            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8614        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8615            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8616        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8617            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8618        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8619            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8620        } else {
8621            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8622        }
8623    }
8624
8625    private void fillInProcMemInfo(ProcessRecord app,
8626            ActivityManager.RunningAppProcessInfo outInfo) {
8627        outInfo.pid = app.pid;
8628        outInfo.uid = app.info.uid;
8629        if (mHeavyWeightProcess == app) {
8630            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8631        }
8632        if (app.persistent) {
8633            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8634        }
8635        if (app.hasActivities) {
8636            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8637        }
8638        outInfo.lastTrimLevel = app.trimMemoryLevel;
8639        int adj = app.curAdj;
8640        outInfo.importance = oomAdjToImportance(adj, outInfo);
8641        outInfo.importanceReasonCode = app.adjTypeCode;
8642    }
8643
8644    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8645        enforceNotIsolatedCaller("getRunningAppProcesses");
8646        // Lazy instantiation of list
8647        List<ActivityManager.RunningAppProcessInfo> runList = null;
8648        final boolean allUsers = ActivityManager.checkUidPermission(
8649                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8650                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8651        int userId = UserHandle.getUserId(Binder.getCallingUid());
8652        synchronized (this) {
8653            // Iterate across all processes
8654            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8655                ProcessRecord app = mLruProcesses.get(i);
8656                if (!allUsers && app.userId != userId) {
8657                    continue;
8658                }
8659                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8660                    // Generate process state info for running application
8661                    ActivityManager.RunningAppProcessInfo currApp =
8662                        new ActivityManager.RunningAppProcessInfo(app.processName,
8663                                app.pid, app.getPackageList());
8664                    fillInProcMemInfo(app, currApp);
8665                    if (app.adjSource instanceof ProcessRecord) {
8666                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8667                        currApp.importanceReasonImportance = oomAdjToImportance(
8668                                app.adjSourceOom, null);
8669                    } else if (app.adjSource instanceof ActivityRecord) {
8670                        ActivityRecord r = (ActivityRecord)app.adjSource;
8671                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8672                    }
8673                    if (app.adjTarget instanceof ComponentName) {
8674                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8675                    }
8676                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8677                    //        + " lru=" + currApp.lru);
8678                    if (runList == null) {
8679                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8680                    }
8681                    runList.add(currApp);
8682                }
8683            }
8684        }
8685        return runList;
8686    }
8687
8688    public List<ApplicationInfo> getRunningExternalApplications() {
8689        enforceNotIsolatedCaller("getRunningExternalApplications");
8690        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8691        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8692        if (runningApps != null && runningApps.size() > 0) {
8693            Set<String> extList = new HashSet<String>();
8694            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8695                if (app.pkgList != null) {
8696                    for (String pkg : app.pkgList) {
8697                        extList.add(pkg);
8698                    }
8699                }
8700            }
8701            IPackageManager pm = AppGlobals.getPackageManager();
8702            for (String pkg : extList) {
8703                try {
8704                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8705                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8706                        retList.add(info);
8707                    }
8708                } catch (RemoteException e) {
8709                }
8710            }
8711        }
8712        return retList;
8713    }
8714
8715    @Override
8716    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8717        enforceNotIsolatedCaller("getMyMemoryState");
8718        synchronized (this) {
8719            ProcessRecord proc;
8720            synchronized (mPidsSelfLocked) {
8721                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8722            }
8723            fillInProcMemInfo(proc, outInfo);
8724        }
8725    }
8726
8727    @Override
8728    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8729        if (checkCallingPermission(android.Manifest.permission.DUMP)
8730                != PackageManager.PERMISSION_GRANTED) {
8731            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8732                    + Binder.getCallingPid()
8733                    + ", uid=" + Binder.getCallingUid()
8734                    + " without permission "
8735                    + android.Manifest.permission.DUMP);
8736            return;
8737        }
8738
8739        boolean dumpAll = false;
8740        boolean dumpClient = false;
8741        String dumpPackage = null;
8742
8743        int opti = 0;
8744        while (opti < args.length) {
8745            String opt = args[opti];
8746            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8747                break;
8748            }
8749            opti++;
8750            if ("-a".equals(opt)) {
8751                dumpAll = true;
8752            } else if ("-c".equals(opt)) {
8753                dumpClient = true;
8754            } else if ("-h".equals(opt)) {
8755                pw.println("Activity manager dump options:");
8756                pw.println("  [-a] [-c] [-h] [cmd] ...");
8757                pw.println("  cmd may be one of:");
8758                pw.println("    a[ctivities]: activity stack state");
8759                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8760                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8761                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8762                pw.println("    o[om]: out of memory management");
8763                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8764                pw.println("    provider [COMP_SPEC]: provider client-side state");
8765                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8766                pw.println("    service [COMP_SPEC]: service client-side state");
8767                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8768                pw.println("    all: dump all activities");
8769                pw.println("    top: dump the top activity");
8770                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8771                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8772                pw.println("    a partial substring in a component name, a");
8773                pw.println("    hex object identifier.");
8774                pw.println("  -a: include all available server state.");
8775                pw.println("  -c: include client state.");
8776                return;
8777            } else {
8778                pw.println("Unknown argument: " + opt + "; use -h for help");
8779            }
8780        }
8781
8782        long origId = Binder.clearCallingIdentity();
8783        boolean more = false;
8784        // Is the caller requesting to dump a particular piece of data?
8785        if (opti < args.length) {
8786            String cmd = args[opti];
8787            opti++;
8788            if ("activities".equals(cmd) || "a".equals(cmd)) {
8789                synchronized (this) {
8790                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8791                }
8792            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8793                String[] newArgs;
8794                String name;
8795                if (opti >= args.length) {
8796                    name = null;
8797                    newArgs = EMPTY_STRING_ARRAY;
8798                } else {
8799                    name = args[opti];
8800                    opti++;
8801                    newArgs = new String[args.length - opti];
8802                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8803                            args.length - opti);
8804                }
8805                synchronized (this) {
8806                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8807                }
8808            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8809                String[] newArgs;
8810                String name;
8811                if (opti >= args.length) {
8812                    name = null;
8813                    newArgs = EMPTY_STRING_ARRAY;
8814                } else {
8815                    name = args[opti];
8816                    opti++;
8817                    newArgs = new String[args.length - opti];
8818                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8819                            args.length - opti);
8820                }
8821                synchronized (this) {
8822                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8823                }
8824            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8825                String[] newArgs;
8826                String name;
8827                if (opti >= args.length) {
8828                    name = null;
8829                    newArgs = EMPTY_STRING_ARRAY;
8830                } else {
8831                    name = args[opti];
8832                    opti++;
8833                    newArgs = new String[args.length - opti];
8834                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8835                            args.length - opti);
8836                }
8837                synchronized (this) {
8838                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8839                }
8840            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8841                synchronized (this) {
8842                    dumpOomLocked(fd, pw, args, opti, true);
8843                }
8844            } else if ("provider".equals(cmd)) {
8845                String[] newArgs;
8846                String name;
8847                if (opti >= args.length) {
8848                    name = null;
8849                    newArgs = EMPTY_STRING_ARRAY;
8850                } else {
8851                    name = args[opti];
8852                    opti++;
8853                    newArgs = new String[args.length - opti];
8854                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8855                }
8856                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8857                    pw.println("No providers match: " + name);
8858                    pw.println("Use -h for help.");
8859                }
8860            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8861                synchronized (this) {
8862                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8863                }
8864            } else if ("service".equals(cmd)) {
8865                String[] newArgs;
8866                String name;
8867                if (opti >= args.length) {
8868                    name = null;
8869                    newArgs = EMPTY_STRING_ARRAY;
8870                } else {
8871                    name = args[opti];
8872                    opti++;
8873                    newArgs = new String[args.length - opti];
8874                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8875                            args.length - opti);
8876                }
8877                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8878                    pw.println("No services match: " + name);
8879                    pw.println("Use -h for help.");
8880                }
8881            } else if ("package".equals(cmd)) {
8882                String[] newArgs;
8883                if (opti >= args.length) {
8884                    pw.println("package: no package name specified");
8885                    pw.println("Use -h for help.");
8886                } else {
8887                    dumpPackage = args[opti];
8888                    opti++;
8889                    newArgs = new String[args.length - opti];
8890                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8891                            args.length - opti);
8892                    args = newArgs;
8893                    opti = 0;
8894                    more = true;
8895                }
8896            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8897                synchronized (this) {
8898                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8899                }
8900            } else {
8901                // Dumping a single activity?
8902                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8903                    pw.println("Bad activity command, or no activities match: " + cmd);
8904                    pw.println("Use -h for help.");
8905                }
8906            }
8907            if (!more) {
8908                Binder.restoreCallingIdentity(origId);
8909                return;
8910            }
8911        }
8912
8913        // No piece of data specified, dump everything.
8914        synchronized (this) {
8915            boolean needSep;
8916            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8917            if (needSep) {
8918                pw.println(" ");
8919            }
8920            if (dumpAll) {
8921                pw.println("-------------------------------------------------------------------------------");
8922            }
8923            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8924            if (needSep) {
8925                pw.println(" ");
8926            }
8927            if (dumpAll) {
8928                pw.println("-------------------------------------------------------------------------------");
8929            }
8930            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8931            if (needSep) {
8932                pw.println(" ");
8933            }
8934            if (dumpAll) {
8935                pw.println("-------------------------------------------------------------------------------");
8936            }
8937            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8938            if (needSep) {
8939                pw.println(" ");
8940            }
8941            if (dumpAll) {
8942                pw.println("-------------------------------------------------------------------------------");
8943            }
8944            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8945            if (needSep) {
8946                pw.println(" ");
8947            }
8948            if (dumpAll) {
8949                pw.println("-------------------------------------------------------------------------------");
8950            }
8951            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8952        }
8953        Binder.restoreCallingIdentity(origId);
8954    }
8955
8956    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8957            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8958        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8959        pw.println("  Main stack:");
8960        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8961                dumpPackage);
8962        pw.println(" ");
8963        pw.println("  Running activities (most recent first):");
8964        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8965                dumpPackage);
8966        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8967            pw.println(" ");
8968            pw.println("  Activities waiting for another to become visible:");
8969            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8970                    !dumpAll, false, dumpPackage);
8971        }
8972        if (mMainStack.mStoppingActivities.size() > 0) {
8973            pw.println(" ");
8974            pw.println("  Activities waiting to stop:");
8975            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8976                    !dumpAll, false, dumpPackage);
8977        }
8978        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8979            pw.println(" ");
8980            pw.println("  Activities waiting to sleep:");
8981            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8982                    !dumpAll, false, dumpPackage);
8983        }
8984        if (mMainStack.mFinishingActivities.size() > 0) {
8985            pw.println(" ");
8986            pw.println("  Activities waiting to finish:");
8987            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8988                    !dumpAll, false, dumpPackage);
8989        }
8990
8991        pw.println(" ");
8992        if (mMainStack.mPausingActivity != null) {
8993            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8994        }
8995        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8996        pw.println("  mFocusedActivity: " + mFocusedActivity);
8997        if (dumpAll) {
8998            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8999            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
9000            pw.println("  mDismissKeyguardOnNextActivity: "
9001                    + mMainStack.mDismissKeyguardOnNextActivity);
9002        }
9003
9004        if (mRecentTasks.size() > 0) {
9005            pw.println();
9006            pw.println("  Recent tasks:");
9007
9008            final int N = mRecentTasks.size();
9009            for (int i=0; i<N; i++) {
9010                TaskRecord tr = mRecentTasks.get(i);
9011                if (dumpPackage != null) {
9012                    if (tr.realActivity == null ||
9013                            !dumpPackage.equals(tr.realActivity)) {
9014                        continue;
9015                    }
9016                }
9017                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9018                        pw.println(tr);
9019                if (dumpAll) {
9020                    mRecentTasks.get(i).dump(pw, "    ");
9021                }
9022            }
9023        }
9024
9025        if (dumpAll) {
9026            pw.println(" ");
9027            pw.println("  mCurTask: " + mCurTask);
9028        }
9029
9030        return true;
9031    }
9032
9033    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9034            int opti, boolean dumpAll, String dumpPackage) {
9035        boolean needSep = false;
9036        int numPers = 0;
9037
9038        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9039
9040        if (dumpAll) {
9041            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9042                final int NA = procs.size();
9043                for (int ia=0; ia<NA; ia++) {
9044                    ProcessRecord r = procs.valueAt(ia);
9045                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9046                        continue;
9047                    }
9048                    if (!needSep) {
9049                        pw.println("  All known processes:");
9050                        needSep = true;
9051                    }
9052                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9053                        pw.print(" UID "); pw.print(procs.keyAt(ia));
9054                        pw.print(" "); pw.println(r);
9055                    r.dump(pw, "    ");
9056                    if (r.persistent) {
9057                        numPers++;
9058                    }
9059                }
9060            }
9061        }
9062
9063        if (mIsolatedProcesses.size() > 0) {
9064            if (needSep) pw.println(" ");
9065            needSep = true;
9066            pw.println("  Isolated process list (sorted by uid):");
9067            for (int i=0; i<mIsolatedProcesses.size(); i++) {
9068                ProcessRecord r = mIsolatedProcesses.valueAt(i);
9069                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9070                    continue;
9071                }
9072                pw.println(String.format("%sIsolated #%2d: %s",
9073                        "    ", i, r.toString()));
9074            }
9075        }
9076
9077        if (mLruProcesses.size() > 0) {
9078            if (needSep) pw.println(" ");
9079            needSep = true;
9080            pw.println("  Process LRU list (sorted by oom_adj):");
9081            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9082                    "Proc", "PERS", false, dumpPackage);
9083            needSep = true;
9084        }
9085
9086        if (dumpAll) {
9087            synchronized (mPidsSelfLocked) {
9088                boolean printed = false;
9089                for (int i=0; i<mPidsSelfLocked.size(); i++) {
9090                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
9091                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9092                        continue;
9093                    }
9094                    if (!printed) {
9095                        if (needSep) pw.println(" ");
9096                        needSep = true;
9097                        pw.println("  PID mappings:");
9098                        printed = true;
9099                    }
9100                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9101                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9102                }
9103            }
9104        }
9105
9106        if (mForegroundProcesses.size() > 0) {
9107            synchronized (mPidsSelfLocked) {
9108                boolean printed = false;
9109                for (int i=0; i<mForegroundProcesses.size(); i++) {
9110                    ProcessRecord r = mPidsSelfLocked.get(
9111                            mForegroundProcesses.valueAt(i).pid);
9112                    if (dumpPackage != null && (r == null
9113                            || !dumpPackage.equals(r.info.packageName))) {
9114                        continue;
9115                    }
9116                    if (!printed) {
9117                        if (needSep) pw.println(" ");
9118                        needSep = true;
9119                        pw.println("  Foreground Processes:");
9120                        printed = true;
9121                    }
9122                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9123                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9124                }
9125            }
9126        }
9127
9128        if (mPersistentStartingProcesses.size() > 0) {
9129            if (needSep) pw.println(" ");
9130            needSep = true;
9131            pw.println("  Persisent processes that are starting:");
9132            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9133                    "Starting Norm", "Restarting PERS", dumpPackage);
9134        }
9135
9136        if (mRemovedProcesses.size() > 0) {
9137            if (needSep) pw.println(" ");
9138            needSep = true;
9139            pw.println("  Processes that are being removed:");
9140            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9141                    "Removed Norm", "Removed PERS", dumpPackage);
9142        }
9143
9144        if (mProcessesOnHold.size() > 0) {
9145            if (needSep) pw.println(" ");
9146            needSep = true;
9147            pw.println("  Processes that are on old until the system is ready:");
9148            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9149                    "OnHold Norm", "OnHold PERS", dumpPackage);
9150        }
9151
9152        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9153
9154        if (mProcessCrashTimes.getMap().size() > 0) {
9155            boolean printed = false;
9156            long now = SystemClock.uptimeMillis();
9157            for (Map.Entry<String, SparseArray<Long>> procs
9158                    : mProcessCrashTimes.getMap().entrySet()) {
9159                String pname = procs.getKey();
9160                SparseArray<Long> uids = procs.getValue();
9161                final int N = uids.size();
9162                for (int i=0; i<N; i++) {
9163                    int puid = uids.keyAt(i);
9164                    ProcessRecord r = mProcessNames.get(pname, puid);
9165                    if (dumpPackage != null && (r == null
9166                            || !dumpPackage.equals(r.info.packageName))) {
9167                        continue;
9168                    }
9169                    if (!printed) {
9170                        if (needSep) pw.println(" ");
9171                        needSep = true;
9172                        pw.println("  Time since processes crashed:");
9173                        printed = true;
9174                    }
9175                    pw.print("    Process "); pw.print(pname);
9176                            pw.print(" uid "); pw.print(puid);
9177                            pw.print(": last crashed ");
9178                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9179                            pw.println(" ago");
9180                }
9181            }
9182        }
9183
9184        if (mBadProcesses.getMap().size() > 0) {
9185            boolean printed = false;
9186            for (Map.Entry<String, SparseArray<Long>> procs
9187                    : mBadProcesses.getMap().entrySet()) {
9188                String pname = procs.getKey();
9189                SparseArray<Long> uids = procs.getValue();
9190                final int N = uids.size();
9191                for (int i=0; i<N; i++) {
9192                    int puid = uids.keyAt(i);
9193                    ProcessRecord r = mProcessNames.get(pname, puid);
9194                    if (dumpPackage != null && (r == null
9195                            || !dumpPackage.equals(r.info.packageName))) {
9196                        continue;
9197                    }
9198                    if (!printed) {
9199                        if (needSep) pw.println(" ");
9200                        needSep = true;
9201                        pw.println("  Bad processes:");
9202                    }
9203                    pw.print("    Bad process "); pw.print(pname);
9204                            pw.print(" uid "); pw.print(puid);
9205                            pw.print(": crashed at time ");
9206                            pw.println(uids.valueAt(i));
9207                }
9208            }
9209        }
9210
9211        pw.println();
9212        pw.println("  mStartedUsers:");
9213        for (int i=0; i<mStartedUsers.size(); i++) {
9214            UserStartedState uss = mStartedUsers.valueAt(i);
9215            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9216                    pw.print(": "); uss.dump("", pw);
9217        }
9218        pw.print("  mUserLru: [");
9219        for (int i=0; i<mUserLru.size(); i++) {
9220            if (i > 0) pw.print(", ");
9221            pw.print(mUserLru.get(i));
9222        }
9223        pw.println("]");
9224        pw.println("  mHomeProcess: " + mHomeProcess);
9225        pw.println("  mPreviousProcess: " + mPreviousProcess);
9226        if (dumpAll) {
9227            StringBuilder sb = new StringBuilder(128);
9228            sb.append("  mPreviousProcessVisibleTime: ");
9229            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9230            pw.println(sb);
9231        }
9232        if (mHeavyWeightProcess != null) {
9233            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9234        }
9235        pw.println("  mConfiguration: " + mConfiguration);
9236        if (dumpAll) {
9237            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9238            if (mCompatModePackages.getPackages().size() > 0) {
9239                boolean printed = false;
9240                for (Map.Entry<String, Integer> entry
9241                        : mCompatModePackages.getPackages().entrySet()) {
9242                    String pkg = entry.getKey();
9243                    int mode = entry.getValue();
9244                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9245                        continue;
9246                    }
9247                    if (!printed) {
9248                        pw.println("  mScreenCompatPackages:");
9249                        printed = true;
9250                    }
9251                    pw.print("    "); pw.print(pkg); pw.print(": ");
9252                            pw.print(mode); pw.println();
9253                }
9254            }
9255        }
9256        if (mSleeping || mWentToSleep || mLockScreenShown) {
9257            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9258                    + " mLockScreenShown " + mLockScreenShown);
9259        }
9260        if (mShuttingDown) {
9261            pw.println("  mShuttingDown=" + mShuttingDown);
9262        }
9263        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9264                || mOrigWaitForDebugger) {
9265            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9266                    + " mDebugTransient=" + mDebugTransient
9267                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9268        }
9269        if (mOpenGlTraceApp != null) {
9270            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9271        }
9272        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9273                || mProfileFd != null) {
9274            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9275            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9276            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9277                    + mAutoStopProfiler);
9278        }
9279        if (mAlwaysFinishActivities || mController != null) {
9280            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9281                    + " mController=" + mController);
9282        }
9283        if (dumpAll) {
9284            pw.println("  Total persistent processes: " + numPers);
9285            pw.println("  mStartRunning=" + mStartRunning
9286                    + " mProcessesReady=" + mProcessesReady
9287                    + " mSystemReady=" + mSystemReady);
9288            pw.println("  mBooting=" + mBooting
9289                    + " mBooted=" + mBooted
9290                    + " mFactoryTest=" + mFactoryTest);
9291            pw.print("  mLastPowerCheckRealtime=");
9292                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9293                    pw.println("");
9294            pw.print("  mLastPowerCheckUptime=");
9295                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9296                    pw.println("");
9297            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9298            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9299            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9300            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9301                    + " mNumHiddenProcs=" + mNumHiddenProcs
9302                    + " mNumServiceProcs=" + mNumServiceProcs
9303                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9304        }
9305
9306        return true;
9307    }
9308
9309    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9310            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9311        if (mProcessesToGc.size() > 0) {
9312            boolean printed = false;
9313            long now = SystemClock.uptimeMillis();
9314            for (int i=0; i<mProcessesToGc.size(); i++) {
9315                ProcessRecord proc = mProcessesToGc.get(i);
9316                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9317                    continue;
9318                }
9319                if (!printed) {
9320                    if (needSep) pw.println(" ");
9321                    needSep = true;
9322                    pw.println("  Processes that are waiting to GC:");
9323                    printed = true;
9324                }
9325                pw.print("    Process "); pw.println(proc);
9326                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9327                        pw.print(", last gced=");
9328                        pw.print(now-proc.lastRequestedGc);
9329                        pw.print(" ms ago, last lowMem=");
9330                        pw.print(now-proc.lastLowMemory);
9331                        pw.println(" ms ago");
9332
9333            }
9334        }
9335        return needSep;
9336    }
9337
9338    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9339            int opti, boolean dumpAll) {
9340        boolean needSep = false;
9341
9342        if (mLruProcesses.size() > 0) {
9343            if (needSep) pw.println(" ");
9344            needSep = true;
9345            pw.println("  OOM levels:");
9346            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9347            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9348            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9349            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9350            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9351            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9352            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9353            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9354            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9355            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9356            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9357            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9358            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9359
9360            if (needSep) pw.println(" ");
9361            needSep = true;
9362            pw.println("  Process OOM control:");
9363            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9364                    "Proc", "PERS", true, null);
9365            needSep = true;
9366        }
9367
9368        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9369
9370        pw.println();
9371        pw.println("  mHomeProcess: " + mHomeProcess);
9372        pw.println("  mPreviousProcess: " + mPreviousProcess);
9373        if (mHeavyWeightProcess != null) {
9374            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9375        }
9376
9377        return true;
9378    }
9379
9380    /**
9381     * There are three ways to call this:
9382     *  - no provider specified: dump all the providers
9383     *  - a flattened component name that matched an existing provider was specified as the
9384     *    first arg: dump that one provider
9385     *  - the first arg isn't the flattened component name of an existing provider:
9386     *    dump all providers whose component contains the first arg as a substring
9387     */
9388    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9389            int opti, boolean dumpAll) {
9390        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9391    }
9392
9393    static class ItemMatcher {
9394        ArrayList<ComponentName> components;
9395        ArrayList<String> strings;
9396        ArrayList<Integer> objects;
9397        boolean all;
9398
9399        ItemMatcher() {
9400            all = true;
9401        }
9402
9403        void build(String name) {
9404            ComponentName componentName = ComponentName.unflattenFromString(name);
9405            if (componentName != null) {
9406                if (components == null) {
9407                    components = new ArrayList<ComponentName>();
9408                }
9409                components.add(componentName);
9410                all = false;
9411            } else {
9412                int objectId = 0;
9413                // Not a '/' separated full component name; maybe an object ID?
9414                try {
9415                    objectId = Integer.parseInt(name, 16);
9416                    if (objects == null) {
9417                        objects = new ArrayList<Integer>();
9418                    }
9419                    objects.add(objectId);
9420                    all = false;
9421                } catch (RuntimeException e) {
9422                    // Not an integer; just do string match.
9423                    if (strings == null) {
9424                        strings = new ArrayList<String>();
9425                    }
9426                    strings.add(name);
9427                    all = false;
9428                }
9429            }
9430        }
9431
9432        int build(String[] args, int opti) {
9433            for (; opti<args.length; opti++) {
9434                String name = args[opti];
9435                if ("--".equals(name)) {
9436                    return opti+1;
9437                }
9438                build(name);
9439            }
9440            return opti;
9441        }
9442
9443        boolean match(Object object, ComponentName comp) {
9444            if (all) {
9445                return true;
9446            }
9447            if (components != null) {
9448                for (int i=0; i<components.size(); i++) {
9449                    if (components.get(i).equals(comp)) {
9450                        return true;
9451                    }
9452                }
9453            }
9454            if (objects != null) {
9455                for (int i=0; i<objects.size(); i++) {
9456                    if (System.identityHashCode(object) == objects.get(i)) {
9457                        return true;
9458                    }
9459                }
9460            }
9461            if (strings != null) {
9462                String flat = comp.flattenToString();
9463                for (int i=0; i<strings.size(); i++) {
9464                    if (flat.contains(strings.get(i))) {
9465                        return true;
9466                    }
9467                }
9468            }
9469            return false;
9470        }
9471    }
9472
9473    /**
9474     * There are three things that cmd can be:
9475     *  - a flattened component name that matches an existing activity
9476     *  - the cmd arg isn't the flattened component name of an existing activity:
9477     *    dump all activity whose component contains the cmd as a substring
9478     *  - A hex number of the ActivityRecord object instance.
9479     */
9480    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9481            int opti, boolean dumpAll) {
9482        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9483
9484        if ("all".equals(name)) {
9485            synchronized (this) {
9486                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9487                    activities.add(r1);
9488                }
9489            }
9490        } else if ("top".equals(name)) {
9491            synchronized (this) {
9492                final int N = mMainStack.mHistory.size();
9493                if (N > 0) {
9494                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9495                }
9496            }
9497        } else {
9498            ItemMatcher matcher = new ItemMatcher();
9499            matcher.build(name);
9500
9501            synchronized (this) {
9502                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9503                    if (matcher.match(r1, r1.intent.getComponent())) {
9504                        activities.add(r1);
9505                    }
9506                }
9507            }
9508        }
9509
9510        if (activities.size() <= 0) {
9511            return false;
9512        }
9513
9514        String[] newArgs = new String[args.length - opti];
9515        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9516
9517        TaskRecord lastTask = null;
9518        boolean needSep = false;
9519        for (int i=activities.size()-1; i>=0; i--) {
9520            ActivityRecord r = (ActivityRecord)activities.get(i);
9521            if (needSep) {
9522                pw.println();
9523            }
9524            needSep = true;
9525            synchronized (this) {
9526                if (lastTask != r.task) {
9527                    lastTask = r.task;
9528                    pw.print("TASK "); pw.print(lastTask.affinity);
9529                            pw.print(" id="); pw.println(lastTask.taskId);
9530                    if (dumpAll) {
9531                        lastTask.dump(pw, "  ");
9532                    }
9533                }
9534            }
9535            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9536        }
9537        return true;
9538    }
9539
9540    /**
9541     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9542     * there is a thread associated with the activity.
9543     */
9544    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9545            final ActivityRecord r, String[] args, boolean dumpAll) {
9546        String innerPrefix = prefix + "  ";
9547        synchronized (this) {
9548            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9549                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9550                    pw.print(" pid=");
9551                    if (r.app != null) pw.println(r.app.pid);
9552                    else pw.println("(not running)");
9553            if (dumpAll) {
9554                r.dump(pw, innerPrefix);
9555            }
9556        }
9557        if (r.app != null && r.app.thread != null) {
9558            // flush anything that is already in the PrintWriter since the thread is going
9559            // to write to the file descriptor directly
9560            pw.flush();
9561            try {
9562                TransferPipe tp = new TransferPipe();
9563                try {
9564                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9565                            r.appToken, innerPrefix, args);
9566                    tp.go(fd);
9567                } finally {
9568                    tp.kill();
9569                }
9570            } catch (IOException e) {
9571                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9572            } catch (RemoteException e) {
9573                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9574            }
9575        }
9576    }
9577
9578    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9579            int opti, boolean dumpAll, String dumpPackage) {
9580        boolean needSep = false;
9581        boolean onlyHistory = false;
9582
9583        if ("history".equals(dumpPackage)) {
9584            onlyHistory = true;
9585            dumpPackage = null;
9586        }
9587
9588        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9589        if (!onlyHistory && dumpAll) {
9590            if (mRegisteredReceivers.size() > 0) {
9591                boolean printed = false;
9592                Iterator it = mRegisteredReceivers.values().iterator();
9593                while (it.hasNext()) {
9594                    ReceiverList r = (ReceiverList)it.next();
9595                    if (dumpPackage != null && (r.app == null ||
9596                            !dumpPackage.equals(r.app.info.packageName))) {
9597                        continue;
9598                    }
9599                    if (!printed) {
9600                        pw.println("  Registered Receivers:");
9601                        needSep = true;
9602                        printed = true;
9603                    }
9604                    pw.print("  * "); pw.println(r);
9605                    r.dump(pw, "    ");
9606                }
9607            }
9608
9609            if (mReceiverResolver.dump(pw, needSep ?
9610                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9611                    "    ", dumpPackage, false)) {
9612                needSep = true;
9613            }
9614        }
9615
9616        for (BroadcastQueue q : mBroadcastQueues) {
9617            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9618        }
9619
9620        needSep = true;
9621
9622        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9623            for (int user=0; user<mStickyBroadcasts.size(); user++) {
9624                if (needSep) {
9625                    pw.println();
9626                }
9627                needSep = true;
9628                pw.print("  Sticky broadcasts for user ");
9629                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9630                StringBuilder sb = new StringBuilder(128);
9631                for (Map.Entry<String, ArrayList<Intent>> ent
9632                        : mStickyBroadcasts.valueAt(user).entrySet()) {
9633                    pw.print("  * Sticky action "); pw.print(ent.getKey());
9634                    if (dumpAll) {
9635                        pw.println(":");
9636                        ArrayList<Intent> intents = ent.getValue();
9637                        final int N = intents.size();
9638                        for (int i=0; i<N; i++) {
9639                            sb.setLength(0);
9640                            sb.append("    Intent: ");
9641                            intents.get(i).toShortString(sb, false, true, false, false);
9642                            pw.println(sb.toString());
9643                            Bundle bundle = intents.get(i).getExtras();
9644                            if (bundle != null) {
9645                                pw.print("      ");
9646                                pw.println(bundle.toString());
9647                            }
9648                        }
9649                    } else {
9650                        pw.println("");
9651                    }
9652                }
9653            }
9654        }
9655
9656        if (!onlyHistory && dumpAll) {
9657            pw.println();
9658            for (BroadcastQueue queue : mBroadcastQueues) {
9659                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9660                        + queue.mBroadcastsScheduled);
9661            }
9662            pw.println("  mHandler:");
9663            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9664            needSep = true;
9665        }
9666
9667        return needSep;
9668    }
9669
9670    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9671            int opti, boolean dumpAll, String dumpPackage) {
9672        boolean needSep = true;
9673
9674        ItemMatcher matcher = new ItemMatcher();
9675        matcher.build(args, opti);
9676
9677        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9678
9679        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9680
9681        if (mLaunchingProviders.size() > 0) {
9682            boolean printed = false;
9683            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9684                ContentProviderRecord r = mLaunchingProviders.get(i);
9685                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9686                    continue;
9687                }
9688                if (!printed) {
9689                    if (needSep) pw.println(" ");
9690                    needSep = true;
9691                    pw.println("  Launching content providers:");
9692                    printed = true;
9693                }
9694                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9695                        pw.println(r);
9696            }
9697        }
9698
9699        if (mGrantedUriPermissions.size() > 0) {
9700            if (needSep) pw.println();
9701            needSep = true;
9702            pw.println("Granted Uri Permissions:");
9703            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9704                int uid = mGrantedUriPermissions.keyAt(i);
9705                HashMap<Uri, UriPermission> perms
9706                        = mGrantedUriPermissions.valueAt(i);
9707                pw.print("  * UID "); pw.print(uid);
9708                        pw.println(" holds:");
9709                for (UriPermission perm : perms.values()) {
9710                    pw.print("    "); pw.println(perm);
9711                    if (dumpAll) {
9712                        perm.dump(pw, "      ");
9713                    }
9714                }
9715            }
9716            needSep = true;
9717        }
9718
9719        return needSep;
9720    }
9721
9722    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9723            int opti, boolean dumpAll, String dumpPackage) {
9724        boolean needSep = false;
9725
9726        if (mIntentSenderRecords.size() > 0) {
9727            boolean printed = false;
9728            Iterator<WeakReference<PendingIntentRecord>> it
9729                    = mIntentSenderRecords.values().iterator();
9730            while (it.hasNext()) {
9731                WeakReference<PendingIntentRecord> ref = it.next();
9732                PendingIntentRecord rec = ref != null ? ref.get(): null;
9733                if (dumpPackage != null && (rec == null
9734                        || !dumpPackage.equals(rec.key.packageName))) {
9735                    continue;
9736                }
9737                if (!printed) {
9738                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9739                    printed = true;
9740                }
9741                needSep = true;
9742                if (rec != null) {
9743                    pw.print("  * "); pw.println(rec);
9744                    if (dumpAll) {
9745                        rec.dump(pw, "    ");
9746                    }
9747                } else {
9748                    pw.print("  * "); pw.println(ref);
9749                }
9750            }
9751        }
9752
9753        return needSep;
9754    }
9755
9756    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9757            String prefix, String label, boolean complete, boolean brief, boolean client,
9758            String dumpPackage) {
9759        TaskRecord lastTask = null;
9760        boolean needNL = false;
9761        final String innerPrefix = prefix + "      ";
9762        final String[] args = new String[0];
9763        for (int i=list.size()-1; i>=0; i--) {
9764            final ActivityRecord r = (ActivityRecord)list.get(i);
9765            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9766                continue;
9767            }
9768            final boolean full = !brief && (complete || !r.isInHistory());
9769            if (needNL) {
9770                pw.println(" ");
9771                needNL = false;
9772            }
9773            if (lastTask != r.task) {
9774                lastTask = r.task;
9775                pw.print(prefix);
9776                pw.print(full ? "* " : "  ");
9777                pw.println(lastTask);
9778                if (full) {
9779                    lastTask.dump(pw, prefix + "  ");
9780                } else if (complete) {
9781                    // Complete + brief == give a summary.  Isn't that obvious?!?
9782                    if (lastTask.intent != null) {
9783                        pw.print(prefix); pw.print("  ");
9784                                pw.println(lastTask.intent.toInsecureStringWithClip());
9785                    }
9786                }
9787            }
9788            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9789            pw.print(" #"); pw.print(i); pw.print(": ");
9790            pw.println(r);
9791            if (full) {
9792                r.dump(pw, innerPrefix);
9793            } else if (complete) {
9794                // Complete + brief == give a summary.  Isn't that obvious?!?
9795                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9796                if (r.app != null) {
9797                    pw.print(innerPrefix); pw.println(r.app);
9798                }
9799            }
9800            if (client && r.app != null && r.app.thread != null) {
9801                // flush anything that is already in the PrintWriter since the thread is going
9802                // to write to the file descriptor directly
9803                pw.flush();
9804                try {
9805                    TransferPipe tp = new TransferPipe();
9806                    try {
9807                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9808                                r.appToken, innerPrefix, args);
9809                        // Short timeout, since blocking here can
9810                        // deadlock with the application.
9811                        tp.go(fd, 2000);
9812                    } finally {
9813                        tp.kill();
9814                    }
9815                } catch (IOException e) {
9816                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9817                } catch (RemoteException e) {
9818                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9819                }
9820                needNL = true;
9821            }
9822        }
9823    }
9824
9825    private static String buildOomTag(String prefix, String space, int val, int base) {
9826        if (val == base) {
9827            if (space == null) return prefix;
9828            return prefix + "  ";
9829        }
9830        return prefix + "+" + Integer.toString(val-base);
9831    }
9832
9833    private static final int dumpProcessList(PrintWriter pw,
9834            ActivityManagerService service, List list,
9835            String prefix, String normalLabel, String persistentLabel,
9836            String dumpPackage) {
9837        int numPers = 0;
9838        final int N = list.size()-1;
9839        for (int i=N; i>=0; i--) {
9840            ProcessRecord r = (ProcessRecord)list.get(i);
9841            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9842                continue;
9843            }
9844            pw.println(String.format("%s%s #%2d: %s",
9845                    prefix, (r.persistent ? persistentLabel : normalLabel),
9846                    i, r.toString()));
9847            if (r.persistent) {
9848                numPers++;
9849            }
9850        }
9851        return numPers;
9852    }
9853
9854    private static final boolean dumpProcessOomList(PrintWriter pw,
9855            ActivityManagerService service, List<ProcessRecord> origList,
9856            String prefix, String normalLabel, String persistentLabel,
9857            boolean inclDetails, String dumpPackage) {
9858
9859        ArrayList<Pair<ProcessRecord, Integer>> list
9860                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9861        for (int i=0; i<origList.size(); i++) {
9862            ProcessRecord r = origList.get(i);
9863            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9864                continue;
9865            }
9866            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9867        }
9868
9869        if (list.size() <= 0) {
9870            return false;
9871        }
9872
9873        Comparator<Pair<ProcessRecord, Integer>> comparator
9874                = new Comparator<Pair<ProcessRecord, Integer>>() {
9875            @Override
9876            public int compare(Pair<ProcessRecord, Integer> object1,
9877                    Pair<ProcessRecord, Integer> object2) {
9878                if (object1.first.setAdj != object2.first.setAdj) {
9879                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9880                }
9881                if (object1.second.intValue() != object2.second.intValue()) {
9882                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9883                }
9884                return 0;
9885            }
9886        };
9887
9888        Collections.sort(list, comparator);
9889
9890        final long curRealtime = SystemClock.elapsedRealtime();
9891        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9892        final long curUptime = SystemClock.uptimeMillis();
9893        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9894
9895        for (int i=list.size()-1; i>=0; i--) {
9896            ProcessRecord r = list.get(i).first;
9897            String oomAdj;
9898            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9899                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9900            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9901                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9902            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9903                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9904            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9905                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9906            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9907                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9908            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9909                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9910            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9911                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9912            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9913                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9914            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9915                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9916            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9917                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9918            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9919                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9920            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9921                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9922            } else {
9923                oomAdj = Integer.toString(r.setAdj);
9924            }
9925            String schedGroup;
9926            switch (r.setSchedGroup) {
9927                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9928                    schedGroup = "B";
9929                    break;
9930                case Process.THREAD_GROUP_DEFAULT:
9931                    schedGroup = "F";
9932                    break;
9933                default:
9934                    schedGroup = Integer.toString(r.setSchedGroup);
9935                    break;
9936            }
9937            String foreground;
9938            if (r.foregroundActivities) {
9939                foreground = "A";
9940            } else if (r.foregroundServices) {
9941                foreground = "S";
9942            } else {
9943                foreground = " ";
9944            }
9945            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9946                    prefix, (r.persistent ? persistentLabel : normalLabel),
9947                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9948                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9949            if (r.adjSource != null || r.adjTarget != null) {
9950                pw.print(prefix);
9951                pw.print("    ");
9952                if (r.adjTarget instanceof ComponentName) {
9953                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9954                } else if (r.adjTarget != null) {
9955                    pw.print(r.adjTarget.toString());
9956                } else {
9957                    pw.print("{null}");
9958                }
9959                pw.print("<=");
9960                if (r.adjSource instanceof ProcessRecord) {
9961                    pw.print("Proc{");
9962                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9963                    pw.println("}");
9964                } else if (r.adjSource != null) {
9965                    pw.println(r.adjSource.toString());
9966                } else {
9967                    pw.println("{null}");
9968                }
9969            }
9970            if (inclDetails) {
9971                pw.print(prefix);
9972                pw.print("    ");
9973                pw.print("oom: max="); pw.print(r.maxAdj);
9974                pw.print(" hidden="); pw.print(r.hiddenAdj);
9975                pw.print(" empty="); pw.print(r.emptyAdj);
9976                pw.print(" curRaw="); pw.print(r.curRawAdj);
9977                pw.print(" setRaw="); pw.print(r.setRawAdj);
9978                pw.print(" cur="); pw.print(r.curAdj);
9979                pw.print(" set="); pw.println(r.setAdj);
9980                pw.print(prefix);
9981                pw.print("    ");
9982                pw.print("keeping="); pw.print(r.keeping);
9983                pw.print(" hidden="); pw.print(r.hidden);
9984                pw.print(" empty="); pw.print(r.empty);
9985                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
9986
9987                if (!r.keeping) {
9988                    if (r.lastWakeTime != 0) {
9989                        long wtime;
9990                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9991                        synchronized (stats) {
9992                            wtime = stats.getProcessWakeTime(r.info.uid,
9993                                    r.pid, curRealtime);
9994                        }
9995                        long timeUsed = wtime - r.lastWakeTime;
9996                        pw.print(prefix);
9997                        pw.print("    ");
9998                        pw.print("keep awake over ");
9999                        TimeUtils.formatDuration(realtimeSince, pw);
10000                        pw.print(" used ");
10001                        TimeUtils.formatDuration(timeUsed, pw);
10002                        pw.print(" (");
10003                        pw.print((timeUsed*100)/realtimeSince);
10004                        pw.println("%)");
10005                    }
10006                    if (r.lastCpuTime != 0) {
10007                        long timeUsed = r.curCpuTime - r.lastCpuTime;
10008                        pw.print(prefix);
10009                        pw.print("    ");
10010                        pw.print("run cpu over ");
10011                        TimeUtils.formatDuration(uptimeSince, pw);
10012                        pw.print(" used ");
10013                        TimeUtils.formatDuration(timeUsed, pw);
10014                        pw.print(" (");
10015                        pw.print((timeUsed*100)/uptimeSince);
10016                        pw.println("%)");
10017                    }
10018                }
10019            }
10020        }
10021        return true;
10022    }
10023
10024    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10025        ArrayList<ProcessRecord> procs;
10026        synchronized (this) {
10027            if (args != null && args.length > start
10028                    && args[start].charAt(0) != '-') {
10029                procs = new ArrayList<ProcessRecord>();
10030                int pid = -1;
10031                try {
10032                    pid = Integer.parseInt(args[start]);
10033                } catch (NumberFormatException e) {
10034
10035                }
10036                for (int i=mLruProcesses.size()-1; i>=0; i--) {
10037                    ProcessRecord proc = mLruProcesses.get(i);
10038                    if (proc.pid == pid) {
10039                        procs.add(proc);
10040                    } else if (proc.processName.equals(args[start])) {
10041                        procs.add(proc);
10042                    }
10043                }
10044                if (procs.size() <= 0) {
10045                    pw.println("No process found for: " + args[start]);
10046                    return null;
10047                }
10048            } else {
10049                procs = new ArrayList<ProcessRecord>(mLruProcesses);
10050            }
10051        }
10052        return procs;
10053    }
10054
10055    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10056            PrintWriter pw, String[] args) {
10057        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10058        if (procs == null) {
10059            return;
10060        }
10061
10062        long uptime = SystemClock.uptimeMillis();
10063        long realtime = SystemClock.elapsedRealtime();
10064        pw.println("Applications Graphics Acceleration Info:");
10065        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10066
10067        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10068            ProcessRecord r = procs.get(i);
10069            if (r.thread != null) {
10070                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10071                pw.flush();
10072                try {
10073                    TransferPipe tp = new TransferPipe();
10074                    try {
10075                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10076                        tp.go(fd);
10077                    } finally {
10078                        tp.kill();
10079                    }
10080                } catch (IOException e) {
10081                    pw.println("Failure while dumping the app: " + r);
10082                    pw.flush();
10083                } catch (RemoteException e) {
10084                    pw.println("Got a RemoteException while dumping the app " + r);
10085                    pw.flush();
10086                }
10087            }
10088        }
10089    }
10090
10091    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10092        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10093        if (procs == null) {
10094            return;
10095        }
10096
10097        pw.println("Applications Database Info:");
10098
10099        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10100            ProcessRecord r = procs.get(i);
10101            if (r.thread != null) {
10102                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10103                pw.flush();
10104                try {
10105                    TransferPipe tp = new TransferPipe();
10106                    try {
10107                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10108                        tp.go(fd);
10109                    } finally {
10110                        tp.kill();
10111                    }
10112                } catch (IOException e) {
10113                    pw.println("Failure while dumping the app: " + r);
10114                    pw.flush();
10115                } catch (RemoteException e) {
10116                    pw.println("Got a RemoteException while dumping the app " + r);
10117                    pw.flush();
10118                }
10119            }
10120        }
10121    }
10122
10123    final static class MemItem {
10124        final String label;
10125        final String shortLabel;
10126        final long pss;
10127        final int id;
10128        ArrayList<MemItem> subitems;
10129
10130        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10131            label = _label;
10132            shortLabel = _shortLabel;
10133            pss = _pss;
10134            id = _id;
10135        }
10136    }
10137
10138    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10139            boolean sort) {
10140        if (sort) {
10141            Collections.sort(items, new Comparator<MemItem>() {
10142                @Override
10143                public int compare(MemItem lhs, MemItem rhs) {
10144                    if (lhs.pss < rhs.pss) {
10145                        return 1;
10146                    } else if (lhs.pss > rhs.pss) {
10147                        return -1;
10148                    }
10149                    return 0;
10150                }
10151            });
10152        }
10153
10154        for (int i=0; i<items.size(); i++) {
10155            MemItem mi = items.get(i);
10156            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10157            if (mi.subitems != null) {
10158                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10159            }
10160        }
10161    }
10162
10163    // These are in KB.
10164    static final long[] DUMP_MEM_BUCKETS = new long[] {
10165        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10166        120*1024, 160*1024, 200*1024,
10167        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10168        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10169    };
10170
10171    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10172            boolean stackLike) {
10173        int start = label.lastIndexOf('.');
10174        if (start >= 0) start++;
10175        else start = 0;
10176        int end = label.length();
10177        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10178            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10179                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10180                out.append(bucket);
10181                out.append(stackLike ? "MB." : "MB ");
10182                out.append(label, start, end);
10183                return;
10184            }
10185        }
10186        out.append(memKB/1024);
10187        out.append(stackLike ? "MB." : "MB ");
10188        out.append(label, start, end);
10189    }
10190
10191    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10192            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10193            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10194            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10195            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10196    };
10197    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10198            "System", "Persistent", "Foreground",
10199            "Visible", "Perceptible", "Heavy Weight",
10200            "Backup", "A Services", "Home", "Previous",
10201            "B Services", "Background"
10202    };
10203
10204    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10205            PrintWriter pw, String prefix, String[] args, boolean brief,
10206            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10207        boolean dumpAll = false;
10208        boolean oomOnly = false;
10209
10210        int opti = 0;
10211        while (opti < args.length) {
10212            String opt = args[opti];
10213            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10214                break;
10215            }
10216            opti++;
10217            if ("-a".equals(opt)) {
10218                dumpAll = true;
10219            } else if ("--oom".equals(opt)) {
10220                oomOnly = true;
10221            } else if ("-h".equals(opt)) {
10222                pw.println("meminfo dump options: [-a] [--oom] [process]");
10223                pw.println("  -a: include all available information for each process.");
10224                pw.println("  --oom: only show processes organized by oom adj.");
10225                pw.println("If [process] is specified it can be the name or ");
10226                pw.println("pid of a specific process to dump.");
10227                return;
10228            } else {
10229                pw.println("Unknown argument: " + opt + "; use -h for help");
10230            }
10231        }
10232
10233        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10234        if (procs == null) {
10235            return;
10236        }
10237
10238        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10239        long uptime = SystemClock.uptimeMillis();
10240        long realtime = SystemClock.elapsedRealtime();
10241
10242        if (procs.size() == 1 || isCheckinRequest) {
10243            dumpAll = true;
10244        }
10245
10246        if (isCheckinRequest) {
10247            // short checkin version
10248            pw.println(uptime + "," + realtime);
10249            pw.flush();
10250        } else {
10251            pw.println("Applications Memory Usage (kB):");
10252            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10253        }
10254
10255        String[] innerArgs = new String[args.length-opti];
10256        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10257
10258        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10259        long nativePss=0, dalvikPss=0, otherPss=0;
10260        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10261
10262        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10263        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10264                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10265
10266        long totalPss = 0;
10267
10268        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10269            ProcessRecord r = procs.get(i);
10270            if (r.thread != null) {
10271                if (!isCheckinRequest && dumpAll) {
10272                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10273                    pw.flush();
10274                }
10275                Debug.MemoryInfo mi = null;
10276                if (dumpAll) {
10277                    try {
10278                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10279                    } catch (RemoteException e) {
10280                        if (!isCheckinRequest) {
10281                            pw.println("Got RemoteException!");
10282                            pw.flush();
10283                        }
10284                    }
10285                } else {
10286                    mi = new Debug.MemoryInfo();
10287                    Debug.getMemoryInfo(r.pid, mi);
10288                }
10289
10290                if (!isCheckinRequest && mi != null) {
10291                    long myTotalPss = mi.getTotalPss();
10292                    totalPss += myTotalPss;
10293                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10294                            r.processName, myTotalPss, 0);
10295                    procMems.add(pssItem);
10296
10297                    nativePss += mi.nativePss;
10298                    dalvikPss += mi.dalvikPss;
10299                    otherPss += mi.otherPss;
10300                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10301                        long mem = mi.getOtherPss(j);
10302                        miscPss[j] += mem;
10303                        otherPss -= mem;
10304                    }
10305
10306                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10307                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10308                                || oomIndex == (oomPss.length-1)) {
10309                            oomPss[oomIndex] += myTotalPss;
10310                            if (oomProcs[oomIndex] == null) {
10311                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10312                            }
10313                            oomProcs[oomIndex].add(pssItem);
10314                            break;
10315                        }
10316                    }
10317                }
10318            }
10319        }
10320
10321        if (!isCheckinRequest && procs.size() > 1) {
10322            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10323
10324            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10325            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10326            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10327            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10328                String label = Debug.MemoryInfo.getOtherLabel(j);
10329                catMems.add(new MemItem(label, label, miscPss[j], j));
10330            }
10331
10332            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10333            for (int j=0; j<oomPss.length; j++) {
10334                if (oomPss[j] != 0) {
10335                    String label = DUMP_MEM_OOM_LABEL[j];
10336                    MemItem item = new MemItem(label, label, oomPss[j],
10337                            DUMP_MEM_OOM_ADJ[j]);
10338                    item.subitems = oomProcs[j];
10339                    oomMems.add(item);
10340                }
10341            }
10342
10343            if (outTag != null || outStack != null) {
10344                if (outTag != null) {
10345                    appendMemBucket(outTag, totalPss, "total", false);
10346                }
10347                if (outStack != null) {
10348                    appendMemBucket(outStack, totalPss, "total", true);
10349                }
10350                boolean firstLine = true;
10351                for (int i=0; i<oomMems.size(); i++) {
10352                    MemItem miCat = oomMems.get(i);
10353                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10354                        continue;
10355                    }
10356                    if (miCat.id < ProcessList.SERVICE_ADJ
10357                            || miCat.id == ProcessList.HOME_APP_ADJ
10358                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10359                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10360                            outTag.append(" / ");
10361                        }
10362                        if (outStack != null) {
10363                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10364                                if (firstLine) {
10365                                    outStack.append(":");
10366                                    firstLine = false;
10367                                }
10368                                outStack.append("\n\t at ");
10369                            } else {
10370                                outStack.append("$");
10371                            }
10372                        }
10373                        for (int j=0; j<miCat.subitems.size(); j++) {
10374                            MemItem mi = miCat.subitems.get(j);
10375                            if (j > 0) {
10376                                if (outTag != null) {
10377                                    outTag.append(" ");
10378                                }
10379                                if (outStack != null) {
10380                                    outStack.append("$");
10381                                }
10382                            }
10383                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10384                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10385                            }
10386                            if (outStack != null) {
10387                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10388                            }
10389                        }
10390                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10391                            outStack.append("(");
10392                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10393                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10394                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10395                                    outStack.append(":");
10396                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10397                                }
10398                            }
10399                            outStack.append(")");
10400                        }
10401                    }
10402                }
10403            }
10404
10405            if (!brief && !oomOnly) {
10406                pw.println();
10407                pw.println("Total PSS by process:");
10408                dumpMemItems(pw, "  ", procMems, true);
10409                pw.println();
10410            }
10411            pw.println("Total PSS by OOM adjustment:");
10412            dumpMemItems(pw, "  ", oomMems, false);
10413            if (!oomOnly) {
10414                PrintWriter out = categoryPw != null ? categoryPw : pw;
10415                out.println();
10416                out.println("Total PSS by category:");
10417                dumpMemItems(out, "  ", catMems, true);
10418            }
10419            pw.println();
10420            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10421            final int[] SINGLE_LONG_FORMAT = new int[] {
10422                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10423            };
10424            long[] longOut = new long[1];
10425            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10426                    SINGLE_LONG_FORMAT, null, longOut, null);
10427            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10428            longOut[0] = 0;
10429            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10430                    SINGLE_LONG_FORMAT, null, longOut, null);
10431            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10432            longOut[0] = 0;
10433            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10434                    SINGLE_LONG_FORMAT, null, longOut, null);
10435            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10436            longOut[0] = 0;
10437            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10438                    SINGLE_LONG_FORMAT, null, longOut, null);
10439            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10440            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10441                    pw.print(shared); pw.println(" kB");
10442            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10443                    pw.print(voltile); pw.println(" kB volatile");
10444        }
10445    }
10446
10447    /**
10448     * Searches array of arguments for the specified string
10449     * @param args array of argument strings
10450     * @param value value to search for
10451     * @return true if the value is contained in the array
10452     */
10453    private static boolean scanArgs(String[] args, String value) {
10454        if (args != null) {
10455            for (String arg : args) {
10456                if (value.equals(arg)) {
10457                    return true;
10458                }
10459            }
10460        }
10461        return false;
10462    }
10463
10464    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10465            ContentProviderRecord cpr, boolean always) {
10466        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10467
10468        if (!inLaunching || always) {
10469            synchronized (cpr) {
10470                cpr.launchingApp = null;
10471                cpr.notifyAll();
10472            }
10473            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10474            String names[] = cpr.info.authority.split(";");
10475            for (int j = 0; j < names.length; j++) {
10476                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10477            }
10478        }
10479
10480        for (int i=0; i<cpr.connections.size(); i++) {
10481            ContentProviderConnection conn = cpr.connections.get(i);
10482            if (conn.waiting) {
10483                // If this connection is waiting for the provider, then we don't
10484                // need to mess with its process unless we are always removing
10485                // or for some reason the provider is not currently launching.
10486                if (inLaunching && !always) {
10487                    continue;
10488                }
10489            }
10490            ProcessRecord capp = conn.client;
10491            conn.dead = true;
10492            if (conn.stableCount > 0) {
10493                if (!capp.persistent && capp.thread != null
10494                        && capp.pid != 0
10495                        && capp.pid != MY_PID) {
10496                    Slog.i(TAG, "Kill " + capp.processName
10497                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10498                            + " in dying process " + (proc != null ? proc.processName : "??"));
10499                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10500                            capp.processName, capp.setAdj, "dying provider "
10501                                    + cpr.name.toShortString());
10502                    Process.killProcessQuiet(capp.pid);
10503                }
10504            } else if (capp.thread != null && conn.provider.provider != null) {
10505                try {
10506                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10507                } catch (RemoteException e) {
10508                }
10509                // In the protocol here, we don't expect the client to correctly
10510                // clean up this connection, we'll just remove it.
10511                cpr.connections.remove(i);
10512                conn.client.conProviders.remove(conn);
10513            }
10514        }
10515
10516        if (inLaunching && always) {
10517            mLaunchingProviders.remove(cpr);
10518        }
10519        return inLaunching;
10520    }
10521
10522    /**
10523     * Main code for cleaning up a process when it has gone away.  This is
10524     * called both as a result of the process dying, or directly when stopping
10525     * a process when running in single process mode.
10526     */
10527    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10528            boolean restarting, boolean allowRestart, int index) {
10529        if (index >= 0) {
10530            mLruProcesses.remove(index);
10531        }
10532
10533        mProcessesToGc.remove(app);
10534
10535        // Dismiss any open dialogs.
10536        if (app.crashDialog != null) {
10537            app.crashDialog.dismiss();
10538            app.crashDialog = null;
10539        }
10540        if (app.anrDialog != null) {
10541            app.anrDialog.dismiss();
10542            app.anrDialog = null;
10543        }
10544        if (app.waitDialog != null) {
10545            app.waitDialog.dismiss();
10546            app.waitDialog = null;
10547        }
10548
10549        app.crashing = false;
10550        app.notResponding = false;
10551
10552        app.resetPackageList();
10553        app.unlinkDeathRecipient();
10554        app.thread = null;
10555        app.forcingToForeground = null;
10556        app.foregroundServices = false;
10557        app.foregroundActivities = false;
10558        app.hasShownUi = false;
10559        app.hasAboveClient = false;
10560
10561        mServices.killServicesLocked(app, allowRestart);
10562
10563        boolean restart = false;
10564
10565        // Remove published content providers.
10566        if (!app.pubProviders.isEmpty()) {
10567            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10568            while (it.hasNext()) {
10569                ContentProviderRecord cpr = it.next();
10570
10571                final boolean always = app.bad || !allowRestart;
10572                if (removeDyingProviderLocked(app, cpr, always) || always) {
10573                    // We left the provider in the launching list, need to
10574                    // restart it.
10575                    restart = true;
10576                }
10577
10578                cpr.provider = null;
10579                cpr.proc = null;
10580            }
10581            app.pubProviders.clear();
10582        }
10583
10584        // Take care of any launching providers waiting for this process.
10585        if (checkAppInLaunchingProvidersLocked(app, false)) {
10586            restart = true;
10587        }
10588
10589        // Unregister from connected content providers.
10590        if (!app.conProviders.isEmpty()) {
10591            for (int i=0; i<app.conProviders.size(); i++) {
10592                ContentProviderConnection conn = app.conProviders.get(i);
10593                conn.provider.connections.remove(conn);
10594            }
10595            app.conProviders.clear();
10596        }
10597
10598        // At this point there may be remaining entries in mLaunchingProviders
10599        // where we were the only one waiting, so they are no longer of use.
10600        // Look for these and clean up if found.
10601        // XXX Commented out for now.  Trying to figure out a way to reproduce
10602        // the actual situation to identify what is actually going on.
10603        if (false) {
10604            for (int i=0; i<mLaunchingProviders.size(); i++) {
10605                ContentProviderRecord cpr = (ContentProviderRecord)
10606                        mLaunchingProviders.get(i);
10607                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10608                    synchronized (cpr) {
10609                        cpr.launchingApp = null;
10610                        cpr.notifyAll();
10611                    }
10612                }
10613            }
10614        }
10615
10616        skipCurrentReceiverLocked(app);
10617
10618        // Unregister any receivers.
10619        if (app.receivers.size() > 0) {
10620            Iterator<ReceiverList> it = app.receivers.iterator();
10621            while (it.hasNext()) {
10622                removeReceiverLocked(it.next());
10623            }
10624            app.receivers.clear();
10625        }
10626
10627        // If the app is undergoing backup, tell the backup manager about it
10628        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10629            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10630            try {
10631                IBackupManager bm = IBackupManager.Stub.asInterface(
10632                        ServiceManager.getService(Context.BACKUP_SERVICE));
10633                bm.agentDisconnected(app.info.packageName);
10634            } catch (RemoteException e) {
10635                // can't happen; backup manager is local
10636            }
10637        }
10638
10639        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10640            ProcessChangeItem item = mPendingProcessChanges.get(i);
10641            if (item.pid == app.pid) {
10642                mPendingProcessChanges.remove(i);
10643                mAvailProcessChanges.add(item);
10644            }
10645        }
10646        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10647
10648        // If the caller is restarting this app, then leave it in its
10649        // current lists and let the caller take care of it.
10650        if (restarting) {
10651            return;
10652        }
10653
10654        if (!app.persistent || app.isolated) {
10655            if (DEBUG_PROCESSES) Slog.v(TAG,
10656                    "Removing non-persistent process during cleanup: " + app);
10657            mProcessNames.remove(app.processName, app.uid);
10658            mIsolatedProcesses.remove(app.uid);
10659            if (mHeavyWeightProcess == app) {
10660                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10661                        mHeavyWeightProcess.userId, 0));
10662                mHeavyWeightProcess = null;
10663            }
10664        } else if (!app.removed) {
10665            // This app is persistent, so we need to keep its record around.
10666            // If it is not already on the pending app list, add it there
10667            // and start a new process for it.
10668            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10669                mPersistentStartingProcesses.add(app);
10670                restart = true;
10671            }
10672        }
10673        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10674                "Clean-up removing on hold: " + app);
10675        mProcessesOnHold.remove(app);
10676
10677        if (app == mHomeProcess) {
10678            mHomeProcess = null;
10679        }
10680        if (app == mPreviousProcess) {
10681            mPreviousProcess = null;
10682        }
10683
10684        if (restart && !app.isolated) {
10685            // We have components that still need to be running in the
10686            // process, so re-launch it.
10687            mProcessNames.put(app.processName, app.uid, app);
10688            startProcessLocked(app, "restart", app.processName);
10689        } else if (app.pid > 0 && app.pid != MY_PID) {
10690            // Goodbye!
10691            synchronized (mPidsSelfLocked) {
10692                mPidsSelfLocked.remove(app.pid);
10693                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10694            }
10695            app.setPid(0);
10696        }
10697    }
10698
10699    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10700        // Look through the content providers we are waiting to have launched,
10701        // and if any run in this process then either schedule a restart of
10702        // the process or kill the client waiting for it if this process has
10703        // gone bad.
10704        int NL = mLaunchingProviders.size();
10705        boolean restart = false;
10706        for (int i=0; i<NL; i++) {
10707            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10708            if (cpr.launchingApp == app) {
10709                if (!alwaysBad && !app.bad) {
10710                    restart = true;
10711                } else {
10712                    removeDyingProviderLocked(app, cpr, true);
10713                    // cpr should have been removed from mLaunchingProviders
10714                    NL = mLaunchingProviders.size();
10715                    i--;
10716                }
10717            }
10718        }
10719        return restart;
10720    }
10721
10722    // =========================================================
10723    // SERVICES
10724    // =========================================================
10725
10726    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10727            int flags) {
10728        enforceNotIsolatedCaller("getServices");
10729        synchronized (this) {
10730            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10731        }
10732    }
10733
10734    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10735        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10736        synchronized (this) {
10737            return mServices.getRunningServiceControlPanelLocked(name);
10738        }
10739    }
10740
10741    public ComponentName startService(IApplicationThread caller, Intent service,
10742            String resolvedType, int userId) {
10743        enforceNotIsolatedCaller("startService");
10744        // Refuse possible leaked file descriptors
10745        if (service != null && service.hasFileDescriptors() == true) {
10746            throw new IllegalArgumentException("File descriptors passed in Intent");
10747        }
10748
10749        if (DEBUG_SERVICE)
10750            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10751        synchronized(this) {
10752            final int callingPid = Binder.getCallingPid();
10753            final int callingUid = Binder.getCallingUid();
10754            checkValidCaller(callingUid, userId);
10755            final long origId = Binder.clearCallingIdentity();
10756            ComponentName res = mServices.startServiceLocked(caller, service,
10757                    resolvedType, callingPid, callingUid, userId);
10758            Binder.restoreCallingIdentity(origId);
10759            return res;
10760        }
10761    }
10762
10763    ComponentName startServiceInPackage(int uid,
10764            Intent service, String resolvedType, int userId) {
10765        synchronized(this) {
10766            if (DEBUG_SERVICE)
10767                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10768            final long origId = Binder.clearCallingIdentity();
10769            ComponentName res = mServices.startServiceLocked(null, service,
10770                    resolvedType, -1, uid, userId);
10771            Binder.restoreCallingIdentity(origId);
10772            return res;
10773        }
10774    }
10775
10776    public int stopService(IApplicationThread caller, Intent service,
10777            String resolvedType, int userId) {
10778        enforceNotIsolatedCaller("stopService");
10779        // Refuse possible leaked file descriptors
10780        if (service != null && service.hasFileDescriptors() == true) {
10781            throw new IllegalArgumentException("File descriptors passed in Intent");
10782        }
10783
10784        checkValidCaller(Binder.getCallingUid(), userId);
10785
10786        synchronized(this) {
10787            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10788        }
10789    }
10790
10791    public IBinder peekService(Intent service, String resolvedType) {
10792        enforceNotIsolatedCaller("peekService");
10793        // Refuse possible leaked file descriptors
10794        if (service != null && service.hasFileDescriptors() == true) {
10795            throw new IllegalArgumentException("File descriptors passed in Intent");
10796        }
10797        synchronized(this) {
10798            return mServices.peekServiceLocked(service, resolvedType);
10799        }
10800    }
10801
10802    public boolean stopServiceToken(ComponentName className, IBinder token,
10803            int startId) {
10804        synchronized(this) {
10805            return mServices.stopServiceTokenLocked(className, token, startId);
10806        }
10807    }
10808
10809    public void setServiceForeground(ComponentName className, IBinder token,
10810            int id, Notification notification, boolean removeNotification) {
10811        synchronized(this) {
10812            mServices.setServiceForegroundLocked(className, token, id, notification,
10813                    removeNotification);
10814        }
10815    }
10816
10817    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
10818            boolean requireFull, String name, String callerPackage) {
10819        synchronized(this) {
10820            return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll,
10821                    requireFull, name, callerPackage);
10822        }
10823    }
10824
10825    int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll,
10826            boolean requireFull, String name, String callerPackage) {
10827        final int callingUserId = UserHandle.getUserId(callingUid);
10828        if (callingUserId != userId) {
10829            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10830                if ((requireFull || checkComponentPermission(
10831                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10832                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
10833                        && checkComponentPermission(
10834                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10835                                callingPid, callingUid, -1, true)
10836                                != PackageManager.PERMISSION_GRANTED) {
10837                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
10838                        // In this case, they would like to just execute as their
10839                        // owner user instead of failing.
10840                        userId = callingUserId;
10841                    } else {
10842                        StringBuilder builder = new StringBuilder(128);
10843                        builder.append("Permission Denial: ");
10844                        builder.append(name);
10845                        if (callerPackage != null) {
10846                            builder.append(" from ");
10847                            builder.append(callerPackage);
10848                        }
10849                        builder.append(" asks to run as user ");
10850                        builder.append(userId);
10851                        builder.append(" but is calling from user ");
10852                        builder.append(UserHandle.getUserId(callingUid));
10853                        builder.append("; this requires ");
10854                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
10855                        if (!requireFull) {
10856                            builder.append(" or ");
10857                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
10858                        }
10859                        String msg = builder.toString();
10860                        Slog.w(TAG, msg);
10861                        throw new SecurityException(msg);
10862                    }
10863                }
10864            }
10865            if (userId == UserHandle.USER_CURRENT
10866                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
10867                userId = mCurrentUserId;
10868            }
10869            if (!allowAll && userId < 0) {
10870                throw new IllegalArgumentException(
10871                        "Call does not support special user #" + userId);
10872            }
10873        }
10874        return userId;
10875    }
10876
10877    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10878            String className, int flags) {
10879        boolean result = false;
10880        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10881            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10882                if (ActivityManager.checkUidPermission(
10883                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10884                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10885                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10886                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10887                            + " requests FLAG_SINGLE_USER, but app does not hold "
10888                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10889                    Slog.w(TAG, msg);
10890                    throw new SecurityException(msg);
10891                }
10892                result = true;
10893            }
10894        } else if (componentProcessName == aInfo.packageName) {
10895            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10896        } else if ("system".equals(componentProcessName)) {
10897            result = true;
10898        }
10899        if (DEBUG_MU) {
10900            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10901                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10902        }
10903        return result;
10904    }
10905
10906    public int bindService(IApplicationThread caller, IBinder token,
10907            Intent service, String resolvedType,
10908            IServiceConnection connection, int flags, int userId) {
10909        enforceNotIsolatedCaller("bindService");
10910        // Refuse possible leaked file descriptors
10911        if (service != null && service.hasFileDescriptors() == true) {
10912            throw new IllegalArgumentException("File descriptors passed in Intent");
10913        }
10914
10915        synchronized(this) {
10916            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10917                    connection, flags, userId);
10918        }
10919    }
10920
10921    public boolean unbindService(IServiceConnection connection) {
10922        synchronized (this) {
10923            return mServices.unbindServiceLocked(connection);
10924        }
10925    }
10926
10927    public void publishService(IBinder token, Intent intent, IBinder service) {
10928        // Refuse possible leaked file descriptors
10929        if (intent != null && intent.hasFileDescriptors() == true) {
10930            throw new IllegalArgumentException("File descriptors passed in Intent");
10931        }
10932
10933        synchronized(this) {
10934            if (!(token instanceof ServiceRecord)) {
10935                throw new IllegalArgumentException("Invalid service token");
10936            }
10937            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
10938        }
10939    }
10940
10941    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10942        // Refuse possible leaked file descriptors
10943        if (intent != null && intent.hasFileDescriptors() == true) {
10944            throw new IllegalArgumentException("File descriptors passed in Intent");
10945        }
10946
10947        synchronized(this) {
10948            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
10949        }
10950    }
10951
10952    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10953        synchronized(this) {
10954            if (!(token instanceof ServiceRecord)) {
10955                throw new IllegalArgumentException("Invalid service token");
10956            }
10957            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
10958        }
10959    }
10960
10961    // =========================================================
10962    // BACKUP AND RESTORE
10963    // =========================================================
10964
10965    // Cause the target app to be launched if necessary and its backup agent
10966    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10967    // activity manager to announce its creation.
10968    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10969        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10970        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10971
10972        synchronized(this) {
10973            // !!! TODO: currently no check here that we're already bound
10974            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10975            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10976            synchronized (stats) {
10977                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10978            }
10979
10980            // Backup agent is now in use, its package can't be stopped.
10981            try {
10982                AppGlobals.getPackageManager().setPackageStoppedState(
10983                        app.packageName, false, UserHandle.getUserId(app.uid));
10984            } catch (RemoteException e) {
10985            } catch (IllegalArgumentException e) {
10986                Slog.w(TAG, "Failed trying to unstop package "
10987                        + app.packageName + ": " + e);
10988            }
10989
10990            BackupRecord r = new BackupRecord(ss, app, backupMode);
10991            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10992                    ? new ComponentName(app.packageName, app.backupAgentName)
10993                    : new ComponentName("android", "FullBackupAgent");
10994            // startProcessLocked() returns existing proc's record if it's already running
10995            ProcessRecord proc = startProcessLocked(app.processName, app,
10996                    false, 0, "backup", hostingName, false, false);
10997            if (proc == null) {
10998                Slog.e(TAG, "Unable to start backup agent process " + r);
10999                return false;
11000            }
11001
11002            r.app = proc;
11003            mBackupTarget = r;
11004            mBackupAppName = app.packageName;
11005
11006            // Try not to kill the process during backup
11007            updateOomAdjLocked(proc);
11008
11009            // If the process is already attached, schedule the creation of the backup agent now.
11010            // If it is not yet live, this will be done when it attaches to the framework.
11011            if (proc.thread != null) {
11012                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11013                try {
11014                    proc.thread.scheduleCreateBackupAgent(app,
11015                            compatibilityInfoForPackageLocked(app), backupMode);
11016                } catch (RemoteException e) {
11017                    // Will time out on the backup manager side
11018                }
11019            } else {
11020                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11021            }
11022            // Invariants: at this point, the target app process exists and the application
11023            // is either already running or in the process of coming up.  mBackupTarget and
11024            // mBackupAppName describe the app, so that when it binds back to the AM we
11025            // know that it's scheduled for a backup-agent operation.
11026        }
11027
11028        return true;
11029    }
11030
11031    // A backup agent has just come up
11032    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11033        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11034                + " = " + agent);
11035
11036        synchronized(this) {
11037            if (!agentPackageName.equals(mBackupAppName)) {
11038                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11039                return;
11040            }
11041        }
11042
11043        long oldIdent = Binder.clearCallingIdentity();
11044        try {
11045            IBackupManager bm = IBackupManager.Stub.asInterface(
11046                    ServiceManager.getService(Context.BACKUP_SERVICE));
11047            bm.agentConnected(agentPackageName, agent);
11048        } catch (RemoteException e) {
11049            // can't happen; the backup manager service is local
11050        } catch (Exception e) {
11051            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11052            e.printStackTrace();
11053        } finally {
11054            Binder.restoreCallingIdentity(oldIdent);
11055        }
11056    }
11057
11058    // done with this agent
11059    public void unbindBackupAgent(ApplicationInfo appInfo) {
11060        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11061        if (appInfo == null) {
11062            Slog.w(TAG, "unbind backup agent for null app");
11063            return;
11064        }
11065
11066        synchronized(this) {
11067            if (mBackupAppName == null) {
11068                Slog.w(TAG, "Unbinding backup agent with no active backup");
11069                return;
11070            }
11071
11072            if (!mBackupAppName.equals(appInfo.packageName)) {
11073                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11074                return;
11075            }
11076
11077            ProcessRecord proc = mBackupTarget.app;
11078            mBackupTarget = null;
11079            mBackupAppName = null;
11080
11081            // Not backing this app up any more; reset its OOM adjustment
11082            updateOomAdjLocked(proc);
11083
11084            // If the app crashed during backup, 'thread' will be null here
11085            if (proc.thread != null) {
11086                try {
11087                    proc.thread.scheduleDestroyBackupAgent(appInfo,
11088                            compatibilityInfoForPackageLocked(appInfo));
11089                } catch (Exception e) {
11090                    Slog.e(TAG, "Exception when unbinding backup agent:");
11091                    e.printStackTrace();
11092                }
11093            }
11094        }
11095    }
11096    // =========================================================
11097    // BROADCASTS
11098    // =========================================================
11099
11100    private final List getStickiesLocked(String action, IntentFilter filter,
11101            List cur, int userId) {
11102        final ContentResolver resolver = mContext.getContentResolver();
11103        HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11104        if (stickies == null) {
11105            return cur;
11106        }
11107        final ArrayList<Intent> list = stickies.get(action);
11108        if (list == null) {
11109            return cur;
11110        }
11111        int N = list.size();
11112        for (int i=0; i<N; i++) {
11113            Intent intent = list.get(i);
11114            if (filter.match(resolver, intent, true, TAG) >= 0) {
11115                if (cur == null) {
11116                    cur = new ArrayList<Intent>();
11117                }
11118                cur.add(intent);
11119            }
11120        }
11121        return cur;
11122    }
11123
11124    boolean isPendingBroadcastProcessLocked(int pid) {
11125        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11126                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11127    }
11128
11129    void skipPendingBroadcastLocked(int pid) {
11130            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11131            for (BroadcastQueue queue : mBroadcastQueues) {
11132                queue.skipPendingBroadcastLocked(pid);
11133            }
11134    }
11135
11136    // The app just attached; send any pending broadcasts that it should receive
11137    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11138        boolean didSomething = false;
11139        for (BroadcastQueue queue : mBroadcastQueues) {
11140            didSomething |= queue.sendPendingBroadcastsLocked(app);
11141        }
11142        return didSomething;
11143    }
11144
11145    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11146            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11147        enforceNotIsolatedCaller("registerReceiver");
11148        int callingUid;
11149        int callingPid;
11150        synchronized(this) {
11151            ProcessRecord callerApp = null;
11152            if (caller != null) {
11153                callerApp = getRecordForAppLocked(caller);
11154                if (callerApp == null) {
11155                    throw new SecurityException(
11156                            "Unable to find app for caller " + caller
11157                            + " (pid=" + Binder.getCallingPid()
11158                            + ") when registering receiver " + receiver);
11159                }
11160                if (callerApp.info.uid != Process.SYSTEM_UID &&
11161                        !callerApp.pkgList.contains(callerPackage)) {
11162                    throw new SecurityException("Given caller package " + callerPackage
11163                            + " is not running in process " + callerApp);
11164                }
11165                callingUid = callerApp.info.uid;
11166                callingPid = callerApp.pid;
11167            } else {
11168                callerPackage = null;
11169                callingUid = Binder.getCallingUid();
11170                callingPid = Binder.getCallingPid();
11171            }
11172
11173            userId = this.handleIncomingUserLocked(callingPid, callingUid, userId,
11174                    true, true, "registerReceiver", callerPackage);
11175
11176            List allSticky = null;
11177
11178            // Look for any matching sticky broadcasts...
11179            Iterator actions = filter.actionsIterator();
11180            if (actions != null) {
11181                while (actions.hasNext()) {
11182                    String action = (String)actions.next();
11183                    allSticky = getStickiesLocked(action, filter, allSticky,
11184                            UserHandle.USER_ALL);
11185                    allSticky = getStickiesLocked(action, filter, allSticky,
11186                            UserHandle.getUserId(callingUid));
11187                }
11188            } else {
11189                allSticky = getStickiesLocked(null, filter, allSticky,
11190                        UserHandle.USER_ALL);
11191                allSticky = getStickiesLocked(null, filter, allSticky,
11192                        UserHandle.getUserId(callingUid));
11193            }
11194
11195            // The first sticky in the list is returned directly back to
11196            // the client.
11197            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11198
11199            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11200                    + ": " + sticky);
11201
11202            if (receiver == null) {
11203                return sticky;
11204            }
11205
11206            ReceiverList rl
11207                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11208            if (rl == null) {
11209                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11210                        userId, receiver);
11211                if (rl.app != null) {
11212                    rl.app.receivers.add(rl);
11213                } else {
11214                    try {
11215                        receiver.asBinder().linkToDeath(rl, 0);
11216                    } catch (RemoteException e) {
11217                        return sticky;
11218                    }
11219                    rl.linkedToDeath = true;
11220                }
11221                mRegisteredReceivers.put(receiver.asBinder(), rl);
11222            } else if (rl.uid != callingUid) {
11223                throw new IllegalArgumentException(
11224                        "Receiver requested to register for uid " + callingUid
11225                        + " was previously registered for uid " + rl.uid);
11226            } else if (rl.pid != callingPid) {
11227                throw new IllegalArgumentException(
11228                        "Receiver requested to register for pid " + callingPid
11229                        + " was previously registered for pid " + rl.pid);
11230            } else if (rl.userId != userId) {
11231                throw new IllegalArgumentException(
11232                        "Receiver requested to register for user " + userId
11233                        + " was previously registered for user " + rl.userId);
11234            }
11235            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11236                    permission, callingUid, userId);
11237            rl.add(bf);
11238            if (!bf.debugCheck()) {
11239                Slog.w(TAG, "==> For Dynamic broadast");
11240            }
11241            mReceiverResolver.addFilter(bf);
11242
11243            // Enqueue broadcasts for all existing stickies that match
11244            // this filter.
11245            if (allSticky != null) {
11246                ArrayList receivers = new ArrayList();
11247                receivers.add(bf);
11248
11249                int N = allSticky.size();
11250                for (int i=0; i<N; i++) {
11251                    Intent intent = (Intent)allSticky.get(i);
11252                    BroadcastQueue queue = broadcastQueueForIntent(intent);
11253                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11254                            null, -1, -1, null, receivers, null, 0, null, null,
11255                            false, true, true, -1);
11256                    queue.enqueueParallelBroadcastLocked(r);
11257                    queue.scheduleBroadcastsLocked();
11258                }
11259            }
11260
11261            return sticky;
11262        }
11263    }
11264
11265    public void unregisterReceiver(IIntentReceiver receiver) {
11266        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11267
11268        final long origId = Binder.clearCallingIdentity();
11269        try {
11270            boolean doTrim = false;
11271
11272            synchronized(this) {
11273                ReceiverList rl
11274                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11275                if (rl != null) {
11276                    if (rl.curBroadcast != null) {
11277                        BroadcastRecord r = rl.curBroadcast;
11278                        final boolean doNext = finishReceiverLocked(
11279                                receiver.asBinder(), r.resultCode, r.resultData,
11280                                r.resultExtras, r.resultAbort, true);
11281                        if (doNext) {
11282                            doTrim = true;
11283                            r.queue.processNextBroadcast(false);
11284                        }
11285                    }
11286
11287                    if (rl.app != null) {
11288                        rl.app.receivers.remove(rl);
11289                    }
11290                    removeReceiverLocked(rl);
11291                    if (rl.linkedToDeath) {
11292                        rl.linkedToDeath = false;
11293                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11294                    }
11295                }
11296            }
11297
11298            // If we actually concluded any broadcasts, we might now be able
11299            // to trim the recipients' apps from our working set
11300            if (doTrim) {
11301                trimApplications();
11302                return;
11303            }
11304
11305        } finally {
11306            Binder.restoreCallingIdentity(origId);
11307        }
11308    }
11309
11310    void removeReceiverLocked(ReceiverList rl) {
11311        mRegisteredReceivers.remove(rl.receiver.asBinder());
11312        int N = rl.size();
11313        for (int i=0; i<N; i++) {
11314            mReceiverResolver.removeFilter(rl.get(i));
11315        }
11316    }
11317
11318    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11319        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11320            ProcessRecord r = mLruProcesses.get(i);
11321            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11322                try {
11323                    r.thread.dispatchPackageBroadcast(cmd, packages);
11324                } catch (RemoteException ex) {
11325                }
11326            }
11327        }
11328    }
11329
11330    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11331            int[] users) {
11332        List<ResolveInfo> receivers = null;
11333        try {
11334            HashSet<ComponentName> singleUserReceivers = null;
11335            boolean scannedFirstReceivers = false;
11336            for (int user : users) {
11337                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11338                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11339                if (newReceivers != null && newReceivers.size() == 0) {
11340                    newReceivers = null;
11341                }
11342                if (receivers == null) {
11343                    receivers = newReceivers;
11344                } else if (newReceivers != null) {
11345                    // We need to concatenate the additional receivers
11346                    // found with what we have do far.  This would be easy,
11347                    // but we also need to de-dup any receivers that are
11348                    // singleUser.
11349                    if (!scannedFirstReceivers) {
11350                        // Collect any single user receivers we had already retrieved.
11351                        scannedFirstReceivers = true;
11352                        for (int i=0; i<receivers.size(); i++) {
11353                            ResolveInfo ri = receivers.get(i);
11354                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11355                                ComponentName cn = new ComponentName(
11356                                        ri.activityInfo.packageName, ri.activityInfo.name);
11357                                if (singleUserReceivers == null) {
11358                                    singleUserReceivers = new HashSet<ComponentName>();
11359                                }
11360                                singleUserReceivers.add(cn);
11361                            }
11362                        }
11363                    }
11364                    // Add the new results to the existing results, tracking
11365                    // and de-dupping single user receivers.
11366                    for (int i=0; i<newReceivers.size(); i++) {
11367                        ResolveInfo ri = receivers.get(i);
11368                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11369                            ComponentName cn = new ComponentName(
11370                                    ri.activityInfo.packageName, ri.activityInfo.name);
11371                            if (singleUserReceivers == null) {
11372                                singleUserReceivers = new HashSet<ComponentName>();
11373                            }
11374                            if (!singleUserReceivers.contains(cn)) {
11375                                singleUserReceivers.add(cn);
11376                                receivers.add(ri);
11377                            }
11378                        } else {
11379                            receivers.add(ri);
11380                        }
11381                    }
11382                }
11383            }
11384        } catch (RemoteException ex) {
11385            // pm is in same process, this will never happen.
11386        }
11387        return receivers;
11388    }
11389
11390    private final int broadcastIntentLocked(ProcessRecord callerApp,
11391            String callerPackage, Intent intent, String resolvedType,
11392            IIntentReceiver resultTo, int resultCode, String resultData,
11393            Bundle map, String requiredPermission,
11394            boolean ordered, boolean sticky, int callingPid, int callingUid,
11395            int userId) {
11396        intent = new Intent(intent);
11397
11398        // By default broadcasts do not go to stopped apps.
11399        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11400
11401        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11402            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11403            + " ordered=" + ordered + " userid=" + userId);
11404        if ((resultTo != null) && !ordered) {
11405            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11406        }
11407
11408        userId = handleIncomingUserLocked(callingPid, callingUid, userId,
11409                true, false, "broadcast", callerPackage);
11410
11411        // Make sure that the user who is receiving this broadcast is started
11412        // If not, we will just skip it.
11413        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11414            Slog.w(TAG, "Skipping broadcast of " + intent
11415                    + ": user " + userId + " is stopped");
11416            return ActivityManager.BROADCAST_SUCCESS;
11417        }
11418
11419        /*
11420         * Prevent non-system code (defined here to be non-persistent
11421         * processes) from sending protected broadcasts.
11422         */
11423        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11424            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11425            callingUid == 0) {
11426            // Always okay.
11427        } else if (callerApp == null || !callerApp.persistent) {
11428            try {
11429                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11430                        intent.getAction())) {
11431                    String msg = "Permission Denial: not allowed to send broadcast "
11432                            + intent.getAction() + " from pid="
11433                            + callingPid + ", uid=" + callingUid;
11434                    Slog.w(TAG, msg);
11435                    throw new SecurityException(msg);
11436                }
11437            } catch (RemoteException e) {
11438                Slog.w(TAG, "Remote exception", e);
11439                return ActivityManager.BROADCAST_SUCCESS;
11440            }
11441        }
11442
11443        // Handle special intents: if this broadcast is from the package
11444        // manager about a package being removed, we need to remove all of
11445        // its activities from the history stack.
11446        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11447                intent.getAction());
11448        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11449                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11450                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11451                || uidRemoved) {
11452            if (checkComponentPermission(
11453                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11454                    callingPid, callingUid, -1, true)
11455                    == PackageManager.PERMISSION_GRANTED) {
11456                if (uidRemoved) {
11457                    final Bundle intentExtras = intent.getExtras();
11458                    final int uid = intentExtras != null
11459                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11460                    if (uid >= 0) {
11461                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11462                        synchronized (bs) {
11463                            bs.removeUidStatsLocked(uid);
11464                        }
11465                    }
11466                } else {
11467                    // If resources are unavailable just force stop all
11468                    // those packages and flush the attribute cache as well.
11469                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11470                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11471                        if (list != null && (list.length > 0)) {
11472                            for (String pkg : list) {
11473                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11474                            }
11475                            sendPackageBroadcastLocked(
11476                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11477                        }
11478                    } else {
11479                        Uri data = intent.getData();
11480                        String ssp;
11481                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11482                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11483                                forceStopPackageLocked(ssp,
11484                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11485                                        false, userId);
11486                            }
11487                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11488                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11489                                        new String[] {ssp}, userId);
11490                            }
11491                        }
11492                    }
11493                }
11494            } else {
11495                String msg = "Permission Denial: " + intent.getAction()
11496                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11497                        + ", uid=" + callingUid + ")"
11498                        + " requires "
11499                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11500                Slog.w(TAG, msg);
11501                throw new SecurityException(msg);
11502            }
11503
11504        // Special case for adding a package: by default turn on compatibility
11505        // mode.
11506        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11507            Uri data = intent.getData();
11508            String ssp;
11509            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11510                mCompatModePackages.handlePackageAddedLocked(ssp,
11511                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11512            }
11513        }
11514
11515        /*
11516         * If this is the time zone changed action, queue up a message that will reset the timezone
11517         * of all currently running processes. This message will get queued up before the broadcast
11518         * happens.
11519         */
11520        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11521            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11522        }
11523
11524        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11525            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11526        }
11527
11528        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11529            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11530            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11531        }
11532
11533        // Add to the sticky list if requested.
11534        if (sticky) {
11535            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11536                    callingPid, callingUid)
11537                    != PackageManager.PERMISSION_GRANTED) {
11538                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11539                        + callingPid + ", uid=" + callingUid
11540                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11541                Slog.w(TAG, msg);
11542                throw new SecurityException(msg);
11543            }
11544            if (requiredPermission != null) {
11545                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11546                        + " and enforce permission " + requiredPermission);
11547                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11548            }
11549            if (intent.getComponent() != null) {
11550                throw new SecurityException(
11551                        "Sticky broadcasts can't target a specific component");
11552            }
11553            // We use userId directly here, since the "all" target is maintained
11554            // as a separate set of sticky broadcasts.
11555            if (userId != UserHandle.USER_ALL) {
11556                // But first, if this is not a broadcast to all users, then
11557                // make sure it doesn't conflict with an existing broadcast to
11558                // all users.
11559                HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11560                        UserHandle.USER_ALL);
11561                if (stickies != null) {
11562                    ArrayList<Intent> list = stickies.get(intent.getAction());
11563                    if (list != null) {
11564                        int N = list.size();
11565                        int i;
11566                        for (i=0; i<N; i++) {
11567                            if (intent.filterEquals(list.get(i))) {
11568                                throw new IllegalArgumentException(
11569                                        "Sticky broadcast " + intent + " for user "
11570                                        + userId + " conflicts with existing global broadcast");
11571                            }
11572                        }
11573                    }
11574                }
11575            }
11576            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11577            if (stickies == null) {
11578                stickies = new HashMap<String, ArrayList<Intent>>();
11579                mStickyBroadcasts.put(userId, stickies);
11580            }
11581            ArrayList<Intent> list = stickies.get(intent.getAction());
11582            if (list == null) {
11583                list = new ArrayList<Intent>();
11584                stickies.put(intent.getAction(), list);
11585            }
11586            int N = list.size();
11587            int i;
11588            for (i=0; i<N; i++) {
11589                if (intent.filterEquals(list.get(i))) {
11590                    // This sticky already exists, replace it.
11591                    list.set(i, new Intent(intent));
11592                    break;
11593                }
11594            }
11595            if (i >= N) {
11596                list.add(new Intent(intent));
11597            }
11598        }
11599
11600        int[] users;
11601        if (userId == UserHandle.USER_ALL) {
11602            // Caller wants broadcast to go to all started users.
11603            users = new int[mStartedUsers.size()];
11604            for (int i=0; i<mStartedUsers.size(); i++) {
11605                users[i] = mStartedUsers.keyAt(i);
11606            }
11607        } else {
11608            // Caller wants broadcast to go to one specific user.
11609            users = new int[] {userId};
11610        }
11611
11612        // Figure out who all will receive this broadcast.
11613        List receivers = null;
11614        List<BroadcastFilter> registeredReceivers = null;
11615        // Need to resolve the intent to interested receivers...
11616        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11617                 == 0) {
11618            receivers = collectReceiverComponents(intent, resolvedType, users);
11619        }
11620        if (intent.getComponent() == null) {
11621            registeredReceivers = mReceiverResolver.queryIntent(intent,
11622                    resolvedType, false, userId);
11623        }
11624
11625        final boolean replacePending =
11626                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11627
11628        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11629                + " replacePending=" + replacePending);
11630
11631        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11632        if (!ordered && NR > 0) {
11633            // If we are not serializing this broadcast, then send the
11634            // registered receivers separately so they don't wait for the
11635            // components to be launched.
11636            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11637            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11638                    callerPackage, callingPid, callingUid, requiredPermission,
11639                    registeredReceivers, resultTo, resultCode, resultData, map,
11640                    ordered, sticky, false, userId);
11641            if (DEBUG_BROADCAST) Slog.v(
11642                    TAG, "Enqueueing parallel broadcast " + r);
11643            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11644            if (!replaced) {
11645                queue.enqueueParallelBroadcastLocked(r);
11646                queue.scheduleBroadcastsLocked();
11647            }
11648            registeredReceivers = null;
11649            NR = 0;
11650        }
11651
11652        // Merge into one list.
11653        int ir = 0;
11654        if (receivers != null) {
11655            // A special case for PACKAGE_ADDED: do not allow the package
11656            // being added to see this broadcast.  This prevents them from
11657            // using this as a back door to get run as soon as they are
11658            // installed.  Maybe in the future we want to have a special install
11659            // broadcast or such for apps, but we'd like to deliberately make
11660            // this decision.
11661            String skipPackages[] = null;
11662            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11663                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11664                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11665                Uri data = intent.getData();
11666                if (data != null) {
11667                    String pkgName = data.getSchemeSpecificPart();
11668                    if (pkgName != null) {
11669                        skipPackages = new String[] { pkgName };
11670                    }
11671                }
11672            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11673                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11674            }
11675            if (skipPackages != null && (skipPackages.length > 0)) {
11676                for (String skipPackage : skipPackages) {
11677                    if (skipPackage != null) {
11678                        int NT = receivers.size();
11679                        for (int it=0; it<NT; it++) {
11680                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11681                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11682                                receivers.remove(it);
11683                                it--;
11684                                NT--;
11685                            }
11686                        }
11687                    }
11688                }
11689            }
11690
11691            int NT = receivers != null ? receivers.size() : 0;
11692            int it = 0;
11693            ResolveInfo curt = null;
11694            BroadcastFilter curr = null;
11695            while (it < NT && ir < NR) {
11696                if (curt == null) {
11697                    curt = (ResolveInfo)receivers.get(it);
11698                }
11699                if (curr == null) {
11700                    curr = registeredReceivers.get(ir);
11701                }
11702                if (curr.getPriority() >= curt.priority) {
11703                    // Insert this broadcast record into the final list.
11704                    receivers.add(it, curr);
11705                    ir++;
11706                    curr = null;
11707                    it++;
11708                    NT++;
11709                } else {
11710                    // Skip to the next ResolveInfo in the final list.
11711                    it++;
11712                    curt = null;
11713                }
11714            }
11715        }
11716        while (ir < NR) {
11717            if (receivers == null) {
11718                receivers = new ArrayList();
11719            }
11720            receivers.add(registeredReceivers.get(ir));
11721            ir++;
11722        }
11723
11724        if ((receivers != null && receivers.size() > 0)
11725                || resultTo != null) {
11726            BroadcastQueue queue = broadcastQueueForIntent(intent);
11727            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11728                    callerPackage, callingPid, callingUid, requiredPermission,
11729                    receivers, resultTo, resultCode, resultData, map, ordered,
11730                    sticky, false, userId);
11731            if (DEBUG_BROADCAST) Slog.v(
11732                    TAG, "Enqueueing ordered broadcast " + r
11733                    + ": prev had " + queue.mOrderedBroadcasts.size());
11734            if (DEBUG_BROADCAST) {
11735                int seq = r.intent.getIntExtra("seq", -1);
11736                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11737            }
11738            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11739            if (!replaced) {
11740                queue.enqueueOrderedBroadcastLocked(r);
11741                queue.scheduleBroadcastsLocked();
11742            }
11743        }
11744
11745        return ActivityManager.BROADCAST_SUCCESS;
11746    }
11747
11748    final Intent verifyBroadcastLocked(Intent intent) {
11749        // Refuse possible leaked file descriptors
11750        if (intent != null && intent.hasFileDescriptors() == true) {
11751            throw new IllegalArgumentException("File descriptors passed in Intent");
11752        }
11753
11754        int flags = intent.getFlags();
11755
11756        if (!mProcessesReady) {
11757            // if the caller really truly claims to know what they're doing, go
11758            // ahead and allow the broadcast without launching any receivers
11759            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11760                intent = new Intent(intent);
11761                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11762            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11763                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11764                        + " before boot completion");
11765                throw new IllegalStateException("Cannot broadcast before boot completed");
11766            }
11767        }
11768
11769        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11770            throw new IllegalArgumentException(
11771                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11772        }
11773
11774        return intent;
11775    }
11776
11777    public final int broadcastIntent(IApplicationThread caller,
11778            Intent intent, String resolvedType, IIntentReceiver resultTo,
11779            int resultCode, String resultData, Bundle map,
11780            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11781        enforceNotIsolatedCaller("broadcastIntent");
11782        synchronized(this) {
11783            intent = verifyBroadcastLocked(intent);
11784
11785            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11786            final int callingPid = Binder.getCallingPid();
11787            final int callingUid = Binder.getCallingUid();
11788            final long origId = Binder.clearCallingIdentity();
11789            int res = broadcastIntentLocked(callerApp,
11790                    callerApp != null ? callerApp.info.packageName : null,
11791                    intent, resolvedType, resultTo,
11792                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11793                    callingPid, callingUid, userId);
11794            Binder.restoreCallingIdentity(origId);
11795            return res;
11796        }
11797    }
11798
11799    int broadcastIntentInPackage(String packageName, int uid,
11800            Intent intent, String resolvedType, IIntentReceiver resultTo,
11801            int resultCode, String resultData, Bundle map,
11802            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11803        synchronized(this) {
11804            intent = verifyBroadcastLocked(intent);
11805
11806            final long origId = Binder.clearCallingIdentity();
11807            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11808                    resultTo, resultCode, resultData, map, requiredPermission,
11809                    serialized, sticky, -1, uid, userId);
11810            Binder.restoreCallingIdentity(origId);
11811            return res;
11812        }
11813    }
11814
11815    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11816        // Refuse possible leaked file descriptors
11817        if (intent != null && intent.hasFileDescriptors() == true) {
11818            throw new IllegalArgumentException("File descriptors passed in Intent");
11819        }
11820
11821        userId = handleIncomingUserLocked(Binder.getCallingPid(),
11822                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
11823
11824        synchronized(this) {
11825            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11826                    != PackageManager.PERMISSION_GRANTED) {
11827                String msg = "Permission Denial: unbroadcastIntent() from pid="
11828                        + Binder.getCallingPid()
11829                        + ", uid=" + Binder.getCallingUid()
11830                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11831                Slog.w(TAG, msg);
11832                throw new SecurityException(msg);
11833            }
11834            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11835            if (stickies != null) {
11836                ArrayList<Intent> list = stickies.get(intent.getAction());
11837                if (list != null) {
11838                    int N = list.size();
11839                    int i;
11840                    for (i=0; i<N; i++) {
11841                        if (intent.filterEquals(list.get(i))) {
11842                            list.remove(i);
11843                            break;
11844                        }
11845                    }
11846                    if (list.size() <= 0) {
11847                        stickies.remove(intent.getAction());
11848                    }
11849                }
11850                if (stickies.size() <= 0) {
11851                    mStickyBroadcasts.remove(userId);
11852                }
11853            }
11854        }
11855    }
11856
11857    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11858            String resultData, Bundle resultExtras, boolean resultAbort,
11859            boolean explicit) {
11860        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11861        if (r == null) {
11862            Slog.w(TAG, "finishReceiver called but not found on queue");
11863            return false;
11864        }
11865
11866        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11867                explicit);
11868    }
11869
11870    public void finishReceiver(IBinder who, int resultCode, String resultData,
11871            Bundle resultExtras, boolean resultAbort) {
11872        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11873
11874        // Refuse possible leaked file descriptors
11875        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11876            throw new IllegalArgumentException("File descriptors passed in Bundle");
11877        }
11878
11879        final long origId = Binder.clearCallingIdentity();
11880        try {
11881            boolean doNext = false;
11882            BroadcastRecord r = null;
11883
11884            synchronized(this) {
11885                r = broadcastRecordForReceiverLocked(who);
11886                if (r != null) {
11887                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11888                        resultData, resultExtras, resultAbort, true);
11889                }
11890            }
11891
11892            if (doNext) {
11893                r.queue.processNextBroadcast(false);
11894            }
11895            trimApplications();
11896        } finally {
11897            Binder.restoreCallingIdentity(origId);
11898        }
11899    }
11900
11901    // =========================================================
11902    // INSTRUMENTATION
11903    // =========================================================
11904
11905    public boolean startInstrumentation(ComponentName className,
11906            String profileFile, int flags, Bundle arguments,
11907            IInstrumentationWatcher watcher, int userId) {
11908        enforceNotIsolatedCaller("startInstrumentation");
11909        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
11910                userId, false, true, "startInstrumentation", null);
11911        // Refuse possible leaked file descriptors
11912        if (arguments != null && arguments.hasFileDescriptors()) {
11913            throw new IllegalArgumentException("File descriptors passed in Bundle");
11914        }
11915
11916        synchronized(this) {
11917            InstrumentationInfo ii = null;
11918            ApplicationInfo ai = null;
11919            try {
11920                ii = mContext.getPackageManager().getInstrumentationInfo(
11921                    className, STOCK_PM_FLAGS);
11922                ai = AppGlobals.getPackageManager().getApplicationInfo(
11923                        ii.targetPackage, STOCK_PM_FLAGS, userId);
11924            } catch (PackageManager.NameNotFoundException e) {
11925            } catch (RemoteException e) {
11926            }
11927            if (ii == null) {
11928                reportStartInstrumentationFailure(watcher, className,
11929                        "Unable to find instrumentation info for: " + className);
11930                return false;
11931            }
11932            if (ai == null) {
11933                reportStartInstrumentationFailure(watcher, className,
11934                        "Unable to find instrumentation target package: " + ii.targetPackage);
11935                return false;
11936            }
11937
11938            int match = mContext.getPackageManager().checkSignatures(
11939                    ii.targetPackage, ii.packageName);
11940            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11941                String msg = "Permission Denial: starting instrumentation "
11942                        + className + " from pid="
11943                        + Binder.getCallingPid()
11944                        + ", uid=" + Binder.getCallingPid()
11945                        + " not allowed because package " + ii.packageName
11946                        + " does not have a signature matching the target "
11947                        + ii.targetPackage;
11948                reportStartInstrumentationFailure(watcher, className, msg);
11949                throw new SecurityException(msg);
11950            }
11951
11952            final long origId = Binder.clearCallingIdentity();
11953            // Instrumentation can kill and relaunch even persistent processes
11954            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
11955            ProcessRecord app = addAppLocked(ai, false);
11956            app.instrumentationClass = className;
11957            app.instrumentationInfo = ai;
11958            app.instrumentationProfileFile = profileFile;
11959            app.instrumentationArguments = arguments;
11960            app.instrumentationWatcher = watcher;
11961            app.instrumentationResultClass = className;
11962            Binder.restoreCallingIdentity(origId);
11963        }
11964
11965        return true;
11966    }
11967
11968    /**
11969     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11970     * error to the logs, but if somebody is watching, send the report there too.  This enables
11971     * the "am" command to report errors with more information.
11972     *
11973     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11974     * @param cn The component name of the instrumentation.
11975     * @param report The error report.
11976     */
11977    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11978            ComponentName cn, String report) {
11979        Slog.w(TAG, report);
11980        try {
11981            if (watcher != null) {
11982                Bundle results = new Bundle();
11983                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11984                results.putString("Error", report);
11985                watcher.instrumentationStatus(cn, -1, results);
11986            }
11987        } catch (RemoteException e) {
11988            Slog.w(TAG, e);
11989        }
11990    }
11991
11992    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11993        if (app.instrumentationWatcher != null) {
11994            try {
11995                // NOTE:  IInstrumentationWatcher *must* be oneway here
11996                app.instrumentationWatcher.instrumentationFinished(
11997                    app.instrumentationClass,
11998                    resultCode,
11999                    results);
12000            } catch (RemoteException e) {
12001            }
12002        }
12003        app.instrumentationWatcher = null;
12004        app.instrumentationClass = null;
12005        app.instrumentationInfo = null;
12006        app.instrumentationProfileFile = null;
12007        app.instrumentationArguments = null;
12008
12009        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
12010    }
12011
12012    public void finishInstrumentation(IApplicationThread target,
12013            int resultCode, Bundle results) {
12014        int userId = UserHandle.getCallingUserId();
12015        // Refuse possible leaked file descriptors
12016        if (results != null && results.hasFileDescriptors()) {
12017            throw new IllegalArgumentException("File descriptors passed in Intent");
12018        }
12019
12020        synchronized(this) {
12021            ProcessRecord app = getRecordForAppLocked(target);
12022            if (app == null) {
12023                Slog.w(TAG, "finishInstrumentation: no app for " + target);
12024                return;
12025            }
12026            final long origId = Binder.clearCallingIdentity();
12027            finishInstrumentationLocked(app, resultCode, results);
12028            Binder.restoreCallingIdentity(origId);
12029        }
12030    }
12031
12032    // =========================================================
12033    // CONFIGURATION
12034    // =========================================================
12035
12036    public ConfigurationInfo getDeviceConfigurationInfo() {
12037        ConfigurationInfo config = new ConfigurationInfo();
12038        synchronized (this) {
12039            config.reqTouchScreen = mConfiguration.touchscreen;
12040            config.reqKeyboardType = mConfiguration.keyboard;
12041            config.reqNavigation = mConfiguration.navigation;
12042            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12043                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12044                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12045            }
12046            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12047                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12048                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12049            }
12050            config.reqGlEsVersion = GL_ES_VERSION;
12051        }
12052        return config;
12053    }
12054
12055    public Configuration getConfiguration() {
12056        Configuration ci;
12057        synchronized(this) {
12058            ci = new Configuration(mConfiguration);
12059        }
12060        return ci;
12061    }
12062
12063    public void updatePersistentConfiguration(Configuration values) {
12064        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12065                "updateConfiguration()");
12066        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12067                "updateConfiguration()");
12068        if (values == null) {
12069            throw new NullPointerException("Configuration must not be null");
12070        }
12071
12072        synchronized(this) {
12073            final long origId = Binder.clearCallingIdentity();
12074            updateConfigurationLocked(values, null, true, false);
12075            Binder.restoreCallingIdentity(origId);
12076        }
12077    }
12078
12079    public void updateConfiguration(Configuration values) {
12080        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12081                "updateConfiguration()");
12082
12083        synchronized(this) {
12084            if (values == null && mWindowManager != null) {
12085                // sentinel: fetch the current configuration from the window manager
12086                values = mWindowManager.computeNewConfiguration();
12087            }
12088
12089            if (mWindowManager != null) {
12090                mProcessList.applyDisplaySize(mWindowManager);
12091            }
12092
12093            final long origId = Binder.clearCallingIdentity();
12094            if (values != null) {
12095                Settings.System.clearConfiguration(values);
12096            }
12097            updateConfigurationLocked(values, null, false, false);
12098            Binder.restoreCallingIdentity(origId);
12099        }
12100    }
12101
12102    /**
12103     * Do either or both things: (1) change the current configuration, and (2)
12104     * make sure the given activity is running with the (now) current
12105     * configuration.  Returns true if the activity has been left running, or
12106     * false if <var>starting</var> is being destroyed to match the new
12107     * configuration.
12108     * @param persistent TODO
12109     */
12110    boolean updateConfigurationLocked(Configuration values,
12111            ActivityRecord starting, boolean persistent, boolean initLocale) {
12112        // do nothing if we are headless
12113        if (mHeadless) return true;
12114
12115        int changes = 0;
12116
12117        boolean kept = true;
12118
12119        if (values != null) {
12120            Configuration newConfig = new Configuration(mConfiguration);
12121            changes = newConfig.updateFrom(values);
12122            if (changes != 0) {
12123                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12124                    Slog.i(TAG, "Updating configuration to: " + values);
12125                }
12126
12127                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12128
12129                if (values.locale != null && !initLocale) {
12130                    saveLocaleLocked(values.locale,
12131                                     !values.locale.equals(mConfiguration.locale),
12132                                     values.userSetLocale);
12133                }
12134
12135                mConfigurationSeq++;
12136                if (mConfigurationSeq <= 0) {
12137                    mConfigurationSeq = 1;
12138                }
12139                newConfig.seq = mConfigurationSeq;
12140                mConfiguration = newConfig;
12141                Slog.i(TAG, "Config changed: " + newConfig);
12142
12143                final Configuration configCopy = new Configuration(mConfiguration);
12144
12145                // TODO: If our config changes, should we auto dismiss any currently
12146                // showing dialogs?
12147                mShowDialogs = shouldShowDialogs(newConfig);
12148
12149                AttributeCache ac = AttributeCache.instance();
12150                if (ac != null) {
12151                    ac.updateConfiguration(configCopy);
12152                }
12153
12154                // Make sure all resources in our process are updated
12155                // right now, so that anyone who is going to retrieve
12156                // resource values after we return will be sure to get
12157                // the new ones.  This is especially important during
12158                // boot, where the first config change needs to guarantee
12159                // all resources have that config before following boot
12160                // code is executed.
12161                mSystemThread.applyConfigurationToResources(configCopy);
12162
12163                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12164                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12165                    msg.obj = new Configuration(configCopy);
12166                    mHandler.sendMessage(msg);
12167                }
12168
12169                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12170                    ProcessRecord app = mLruProcesses.get(i);
12171                    try {
12172                        if (app.thread != null) {
12173                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12174                                    + app.processName + " new config " + mConfiguration);
12175                            app.thread.scheduleConfigurationChanged(configCopy);
12176                        }
12177                    } catch (Exception e) {
12178                    }
12179                }
12180                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12181                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12182                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
12183                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12184                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12185                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12186                    broadcastIntentLocked(null, null,
12187                            new Intent(Intent.ACTION_LOCALE_CHANGED),
12188                            null, null, 0, null, null,
12189                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12190                }
12191            }
12192        }
12193
12194        if (changes != 0 && starting == null) {
12195            // If the configuration changed, and the caller is not already
12196            // in the process of starting an activity, then find the top
12197            // activity to check if its configuration needs to change.
12198            starting = mMainStack.topRunningActivityLocked(null);
12199        }
12200
12201        if (starting != null) {
12202            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12203            // And we need to make sure at this point that all other activities
12204            // are made visible with the correct configuration.
12205            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12206        }
12207
12208        if (values != null && mWindowManager != null) {
12209            mWindowManager.setNewConfiguration(mConfiguration);
12210        }
12211
12212        return kept;
12213    }
12214
12215    /**
12216     * Decide based on the configuration whether we should shouw the ANR,
12217     * crash, etc dialogs.  The idea is that if there is no affordnace to
12218     * press the on-screen buttons, we shouldn't show the dialog.
12219     *
12220     * A thought: SystemUI might also want to get told about this, the Power
12221     * dialog / global actions also might want different behaviors.
12222     */
12223    private static final boolean shouldShowDialogs(Configuration config) {
12224        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12225                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12226    }
12227
12228    /**
12229     * Save the locale.  You must be inside a synchronized (this) block.
12230     */
12231    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12232        if(isDiff) {
12233            SystemProperties.set("user.language", l.getLanguage());
12234            SystemProperties.set("user.region", l.getCountry());
12235        }
12236
12237        if(isPersist) {
12238            SystemProperties.set("persist.sys.language", l.getLanguage());
12239            SystemProperties.set("persist.sys.country", l.getCountry());
12240            SystemProperties.set("persist.sys.localevar", l.getVariant());
12241        }
12242    }
12243
12244    @Override
12245    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12246        ActivityRecord srec = ActivityRecord.forToken(token);
12247        return srec != null && srec.task.affinity != null &&
12248                srec.task.affinity.equals(destAffinity);
12249    }
12250
12251    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12252            Intent resultData) {
12253        ComponentName dest = destIntent.getComponent();
12254
12255        synchronized (this) {
12256            ActivityRecord srec = ActivityRecord.forToken(token);
12257            if (srec == null) {
12258                return false;
12259            }
12260            ArrayList<ActivityRecord> history = srec.stack.mHistory;
12261            final int start = history.indexOf(srec);
12262            if (start < 0) {
12263                // Current activity is not in history stack; do nothing.
12264                return false;
12265            }
12266            int finishTo = start - 1;
12267            ActivityRecord parent = null;
12268            boolean foundParentInTask = false;
12269            if (dest != null) {
12270                TaskRecord tr = srec.task;
12271                for (int i = start - 1; i >= 0; i--) {
12272                    ActivityRecord r = history.get(i);
12273                    if (tr != r.task) {
12274                        // Couldn't find parent in the same task; stop at the one above this.
12275                        // (Root of current task; in-app "home" behavior)
12276                        // Always at least finish the current activity.
12277                        finishTo = Math.min(start - 1, i + 1);
12278                        parent = history.get(finishTo);
12279                        break;
12280                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
12281                            r.info.name.equals(dest.getClassName())) {
12282                        finishTo = i;
12283                        parent = r;
12284                        foundParentInTask = true;
12285                        break;
12286                    }
12287                }
12288            }
12289
12290            if (mController != null) {
12291                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12292                if (next != null) {
12293                    // ask watcher if this is allowed
12294                    boolean resumeOK = true;
12295                    try {
12296                        resumeOK = mController.activityResuming(next.packageName);
12297                    } catch (RemoteException e) {
12298                        mController = null;
12299                    }
12300
12301                    if (!resumeOK) {
12302                        return false;
12303                    }
12304                }
12305            }
12306            final long origId = Binder.clearCallingIdentity();
12307            for (int i = start; i > finishTo; i--) {
12308                ActivityRecord r = history.get(i);
12309                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12310                        "navigate-up", true);
12311                // Only return the supplied result for the first activity finished
12312                resultCode = Activity.RESULT_CANCELED;
12313                resultData = null;
12314            }
12315
12316            if (parent != null && foundParentInTask) {
12317                final int parentLaunchMode = parent.info.launchMode;
12318                final int destIntentFlags = destIntent.getFlags();
12319                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12320                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12321                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12322                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12323                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12324                } else {
12325                    try {
12326                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12327                                destIntent.getComponent(), 0, UserHandle.getCallingUserId());
12328                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12329                                null, aInfo, parent.appToken, null,
12330                                0, -1, parent.launchedFromUid, 0, null, true, null);
12331                        foundParentInTask = res == ActivityManager.START_SUCCESS;
12332                    } catch (RemoteException e) {
12333                        foundParentInTask = false;
12334                    }
12335                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12336                            resultData, "navigate-up", true);
12337                }
12338            }
12339            Binder.restoreCallingIdentity(origId);
12340            return foundParentInTask;
12341        }
12342    }
12343
12344    public int getLaunchedFromUid(IBinder activityToken) {
12345        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12346        if (srec == null) {
12347            return -1;
12348        }
12349        return srec.launchedFromUid;
12350    }
12351
12352    // =========================================================
12353    // LIFETIME MANAGEMENT
12354    // =========================================================
12355
12356    // Returns which broadcast queue the app is the current [or imminent] receiver
12357    // on, or 'null' if the app is not an active broadcast recipient.
12358    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12359        BroadcastRecord r = app.curReceiver;
12360        if (r != null) {
12361            return r.queue;
12362        }
12363
12364        // It's not the current receiver, but it might be starting up to become one
12365        synchronized (this) {
12366            for (BroadcastQueue queue : mBroadcastQueues) {
12367                r = queue.mPendingBroadcast;
12368                if (r != null && r.curApp == app) {
12369                    // found it; report which queue it's in
12370                    return queue;
12371                }
12372            }
12373        }
12374
12375        return null;
12376    }
12377
12378    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12379            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12380        if (mAdjSeq == app.adjSeq) {
12381            // This adjustment has already been computed.  If we are calling
12382            // from the top, we may have already computed our adjustment with
12383            // an earlier hidden adjustment that isn't really for us... if
12384            // so, use the new hidden adjustment.
12385            if (!recursed && app.hidden) {
12386                app.curAdj = app.curRawAdj = app.nonStoppingAdj =
12387                        app.hasActivities ? hiddenAdj : emptyAdj;
12388            }
12389            return app.curRawAdj;
12390        }
12391
12392        if (app.thread == null) {
12393            app.adjSeq = mAdjSeq;
12394            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12395            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12396        }
12397
12398        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12399        app.adjSource = null;
12400        app.adjTarget = null;
12401        app.empty = false;
12402        app.hidden = false;
12403
12404        final int activitiesSize = app.activities.size();
12405
12406        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12407            // The max adjustment doesn't allow this app to be anything
12408            // below foreground, so it is not worth doing work for it.
12409            app.adjType = "fixed";
12410            app.adjSeq = mAdjSeq;
12411            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12412            app.hasActivities = false;
12413            app.foregroundActivities = false;
12414            app.keeping = true;
12415            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12416            // System process can do UI, and when they do we want to have
12417            // them trim their memory after the user leaves the UI.  To
12418            // facilitate this, here we need to determine whether or not it
12419            // is currently showing UI.
12420            app.systemNoUi = true;
12421            if (app == TOP_APP) {
12422                app.systemNoUi = false;
12423                app.hasActivities = true;
12424            } else if (activitiesSize > 0) {
12425                for (int j = 0; j < activitiesSize; j++) {
12426                    final ActivityRecord r = app.activities.get(j);
12427                    if (r.visible) {
12428                        app.systemNoUi = false;
12429                    }
12430                    if (r.app == app) {
12431                        app.hasActivities = true;
12432                    }
12433                }
12434            }
12435            return (app.curAdj=app.maxAdj);
12436        }
12437
12438        app.keeping = false;
12439        app.systemNoUi = false;
12440        app.hasActivities = false;
12441
12442        // Determine the importance of the process, starting with most
12443        // important to least, and assign an appropriate OOM adjustment.
12444        int adj;
12445        int schedGroup;
12446        boolean foregroundActivities = false;
12447        boolean interesting = false;
12448        BroadcastQueue queue;
12449        if (app == TOP_APP) {
12450            // The last app on the list is the foreground app.
12451            adj = ProcessList.FOREGROUND_APP_ADJ;
12452            schedGroup = Process.THREAD_GROUP_DEFAULT;
12453            app.adjType = "top-activity";
12454            foregroundActivities = true;
12455            interesting = true;
12456            app.hasActivities = true;
12457        } else if (app.instrumentationClass != null) {
12458            // Don't want to kill running instrumentation.
12459            adj = ProcessList.FOREGROUND_APP_ADJ;
12460            schedGroup = Process.THREAD_GROUP_DEFAULT;
12461            app.adjType = "instrumentation";
12462            interesting = true;
12463        } else if ((queue = isReceivingBroadcast(app)) != null) {
12464            // An app that is currently receiving a broadcast also
12465            // counts as being in the foreground for OOM killer purposes.
12466            // It's placed in a sched group based on the nature of the
12467            // broadcast as reflected by which queue it's active in.
12468            adj = ProcessList.FOREGROUND_APP_ADJ;
12469            schedGroup = (queue == mFgBroadcastQueue)
12470                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12471            app.adjType = "broadcast";
12472        } else if (app.executingServices.size() > 0) {
12473            // An app that is currently executing a service callback also
12474            // counts as being in the foreground.
12475            adj = ProcessList.FOREGROUND_APP_ADJ;
12476            schedGroup = Process.THREAD_GROUP_DEFAULT;
12477            app.adjType = "exec-service";
12478        } else {
12479            // Assume process is hidden (has activities); we will correct
12480            // later if this is not the case.
12481            adj = hiddenAdj;
12482            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12483            app.hidden = true;
12484            app.adjType = "bg-activities";
12485        }
12486
12487        boolean hasStoppingActivities = false;
12488
12489        // Examine all activities if not already foreground.
12490        if (!foregroundActivities && activitiesSize > 0) {
12491            for (int j = 0; j < activitiesSize; j++) {
12492                final ActivityRecord r = app.activities.get(j);
12493                if (r.visible) {
12494                    // App has a visible activity; only upgrade adjustment.
12495                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12496                        adj = ProcessList.VISIBLE_APP_ADJ;
12497                        app.adjType = "visible";
12498                    }
12499                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12500                    app.hidden = false;
12501                    app.hasActivities = true;
12502                    foregroundActivities = true;
12503                    break;
12504                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12505                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12506                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12507                        app.adjType = "pausing";
12508                    }
12509                    app.hidden = false;
12510                    foregroundActivities = true;
12511                } else if (r.state == ActivityState.STOPPING) {
12512                    // We will apply the actual adjustment later, because
12513                    // we want to allow this process to immediately go through
12514                    // any memory trimming that is in effect.
12515                    app.hidden = false;
12516                    foregroundActivities = true;
12517                    hasStoppingActivities = true;
12518                }
12519                if (r.app == app) {
12520                    app.hasActivities = true;
12521                }
12522            }
12523        }
12524
12525        if (adj == hiddenAdj && !app.hasActivities) {
12526            // Whoops, this process is completely empty as far as we know
12527            // at this point.
12528            adj = emptyAdj;
12529            app.empty = true;
12530            app.adjType = "bg-empty";
12531        }
12532
12533        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12534            if (app.foregroundServices) {
12535                // The user is aware of this app, so make it visible.
12536                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12537                app.hidden = false;
12538                app.adjType = "foreground-service";
12539                schedGroup = Process.THREAD_GROUP_DEFAULT;
12540            } else if (app.forcingToForeground != null) {
12541                // The user is aware of this app, so make it visible.
12542                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12543                app.hidden = false;
12544                app.adjType = "force-foreground";
12545                app.adjSource = app.forcingToForeground;
12546                schedGroup = Process.THREAD_GROUP_DEFAULT;
12547            }
12548        }
12549
12550        if (app.foregroundServices) {
12551            interesting = true;
12552        }
12553
12554        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12555            // We don't want to kill the current heavy-weight process.
12556            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12557            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12558            app.hidden = false;
12559            app.adjType = "heavy";
12560        }
12561
12562        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12563            // This process is hosting what we currently consider to be the
12564            // home app, so we don't want to let it go into the background.
12565            adj = ProcessList.HOME_APP_ADJ;
12566            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12567            app.hidden = false;
12568            app.adjType = "home";
12569        }
12570
12571        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12572                && app.activities.size() > 0) {
12573            // This was the previous process that showed UI to the user.
12574            // We want to try to keep it around more aggressively, to give
12575            // a good experience around switching between two apps.
12576            adj = ProcessList.PREVIOUS_APP_ADJ;
12577            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12578            app.hidden = false;
12579            app.adjType = "previous";
12580        }
12581
12582        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12583                + " reason=" + app.adjType);
12584
12585        // By default, we use the computed adjustment.  It may be changed if
12586        // there are applications dependent on our services or providers, but
12587        // this gives us a baseline and makes sure we don't get into an
12588        // infinite recursion.
12589        app.adjSeq = mAdjSeq;
12590        app.curRawAdj = app.nonStoppingAdj = adj;
12591
12592        if (mBackupTarget != null && app == mBackupTarget.app) {
12593            // If possible we want to avoid killing apps while they're being backed up
12594            if (adj > ProcessList.BACKUP_APP_ADJ) {
12595                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12596                adj = ProcessList.BACKUP_APP_ADJ;
12597                app.adjType = "backup";
12598                app.hidden = false;
12599            }
12600        }
12601
12602        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12603                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12604            final long now = SystemClock.uptimeMillis();
12605            // This process is more important if the top activity is
12606            // bound to the service.
12607            Iterator<ServiceRecord> jt = app.services.iterator();
12608            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12609                ServiceRecord s = jt.next();
12610                if (s.startRequested) {
12611                    if (app.hasShownUi && app != mHomeProcess) {
12612                        // If this process has shown some UI, let it immediately
12613                        // go to the LRU list because it may be pretty heavy with
12614                        // UI stuff.  We'll tag it with a label just to help
12615                        // debug and understand what is going on.
12616                        if (adj > ProcessList.SERVICE_ADJ) {
12617                            app.adjType = "started-bg-ui-services";
12618                        }
12619                    } else {
12620                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12621                            // This service has seen some activity within
12622                            // recent memory, so we will keep its process ahead
12623                            // of the background processes.
12624                            if (adj > ProcessList.SERVICE_ADJ) {
12625                                adj = ProcessList.SERVICE_ADJ;
12626                                app.adjType = "started-services";
12627                                app.hidden = false;
12628                            }
12629                        }
12630                        // If we have let the service slide into the background
12631                        // state, still have some text describing what it is doing
12632                        // even though the service no longer has an impact.
12633                        if (adj > ProcessList.SERVICE_ADJ) {
12634                            app.adjType = "started-bg-services";
12635                        }
12636                    }
12637                    // Don't kill this process because it is doing work; it
12638                    // has said it is doing work.
12639                    app.keeping = true;
12640                }
12641                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12642                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12643                    Iterator<ArrayList<ConnectionRecord>> kt
12644                            = s.connections.values().iterator();
12645                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12646                        ArrayList<ConnectionRecord> clist = kt.next();
12647                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12648                            // XXX should compute this based on the max of
12649                            // all connected clients.
12650                            ConnectionRecord cr = clist.get(i);
12651                            if (cr.binding.client == app) {
12652                                // Binding to ourself is not interesting.
12653                                continue;
12654                            }
12655                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12656                                ProcessRecord client = cr.binding.client;
12657                                int clientAdj = adj;
12658                                int myHiddenAdj = hiddenAdj;
12659                                if (myHiddenAdj > client.hiddenAdj) {
12660                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12661                                        myHiddenAdj = client.hiddenAdj;
12662                                    } else {
12663                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12664                                    }
12665                                }
12666                                int myEmptyAdj = emptyAdj;
12667                                if (myEmptyAdj > client.emptyAdj) {
12668                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12669                                        myEmptyAdj = client.emptyAdj;
12670                                    } else {
12671                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12672                                    }
12673                                }
12674                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12675                                        myEmptyAdj, TOP_APP, true, doingAll);
12676                                String adjType = null;
12677                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12678                                    // Not doing bind OOM management, so treat
12679                                    // this guy more like a started service.
12680                                    if (app.hasShownUi && app != mHomeProcess) {
12681                                        // If this process has shown some UI, let it immediately
12682                                        // go to the LRU list because it may be pretty heavy with
12683                                        // UI stuff.  We'll tag it with a label just to help
12684                                        // debug and understand what is going on.
12685                                        if (adj > clientAdj) {
12686                                            adjType = "bound-bg-ui-services";
12687                                        }
12688                                        app.hidden = false;
12689                                        clientAdj = adj;
12690                                    } else {
12691                                        if (now >= (s.lastActivity
12692                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12693                                            // This service has not seen activity within
12694                                            // recent memory, so allow it to drop to the
12695                                            // LRU list if there is no other reason to keep
12696                                            // it around.  We'll also tag it with a label just
12697                                            // to help debug and undertand what is going on.
12698                                            if (adj > clientAdj) {
12699                                                adjType = "bound-bg-services";
12700                                            }
12701                                            clientAdj = adj;
12702                                        }
12703                                    }
12704                                }
12705                                if (adj > clientAdj) {
12706                                    // If this process has recently shown UI, and
12707                                    // the process that is binding to it is less
12708                                    // important than being visible, then we don't
12709                                    // care about the binding as much as we care
12710                                    // about letting this process get into the LRU
12711                                    // list to be killed and restarted if needed for
12712                                    // memory.
12713                                    if (app.hasShownUi && app != mHomeProcess
12714                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12715                                        adjType = "bound-bg-ui-services";
12716                                    } else {
12717                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12718                                                |Context.BIND_IMPORTANT)) != 0) {
12719                                            adj = clientAdj;
12720                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12721                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12722                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12723                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12724                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12725                                            adj = clientAdj;
12726                                        } else {
12727                                            app.pendingUiClean = true;
12728                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12729                                                adj = ProcessList.VISIBLE_APP_ADJ;
12730                                            }
12731                                        }
12732                                        if (!client.hidden) {
12733                                            app.hidden = false;
12734                                        }
12735                                        if (client.keeping) {
12736                                            app.keeping = true;
12737                                        }
12738                                        adjType = "service";
12739                                    }
12740                                }
12741                                if (adjType != null) {
12742                                    app.adjType = adjType;
12743                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12744                                            .REASON_SERVICE_IN_USE;
12745                                    app.adjSource = cr.binding.client;
12746                                    app.adjSourceOom = clientAdj;
12747                                    app.adjTarget = s.name;
12748                                }
12749                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12750                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12751                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12752                                    }
12753                                }
12754                            }
12755                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12756                                ActivityRecord a = cr.activity;
12757                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12758                                        (a.visible || a.state == ActivityState.RESUMED
12759                                         || a.state == ActivityState.PAUSING)) {
12760                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12761                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12762                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12763                                    }
12764                                    app.hidden = false;
12765                                    app.adjType = "service";
12766                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12767                                            .REASON_SERVICE_IN_USE;
12768                                    app.adjSource = a;
12769                                    app.adjSourceOom = adj;
12770                                    app.adjTarget = s.name;
12771                                }
12772                            }
12773                        }
12774                    }
12775                }
12776            }
12777
12778            // Finally, if this process has active services running in it, we
12779            // would like to avoid killing it unless it would prevent the current
12780            // application from running.  By default we put the process in
12781            // with the rest of the background processes; as we scan through
12782            // its services we may bump it up from there.
12783            if (adj > hiddenAdj) {
12784                adj = hiddenAdj;
12785                app.hidden = false;
12786                app.adjType = "bg-services";
12787            }
12788        }
12789
12790        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12791                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12792            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12793            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12794                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12795                ContentProviderRecord cpr = jt.next();
12796                for (int i = cpr.connections.size()-1;
12797                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12798                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12799                        i--) {
12800                    ContentProviderConnection conn = cpr.connections.get(i);
12801                    ProcessRecord client = conn.client;
12802                    if (client == app) {
12803                        // Being our own client is not interesting.
12804                        continue;
12805                    }
12806                    int myHiddenAdj = hiddenAdj;
12807                    if (myHiddenAdj > client.hiddenAdj) {
12808                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12809                            myHiddenAdj = client.hiddenAdj;
12810                        } else {
12811                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12812                        }
12813                    }
12814                    int myEmptyAdj = emptyAdj;
12815                    if (myEmptyAdj > client.emptyAdj) {
12816                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12817                            myEmptyAdj = client.emptyAdj;
12818                        } else {
12819                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12820                        }
12821                    }
12822                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12823                            myEmptyAdj, TOP_APP, true, doingAll);
12824                    if (adj > clientAdj) {
12825                        if (app.hasShownUi && app != mHomeProcess
12826                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12827                            app.adjType = "bg-ui-provider";
12828                        } else {
12829                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12830                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12831                            app.adjType = "provider";
12832                        }
12833                        if (!client.hidden) {
12834                            app.hidden = false;
12835                        }
12836                        if (client.keeping) {
12837                            app.keeping = true;
12838                        }
12839                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12840                                .REASON_PROVIDER_IN_USE;
12841                        app.adjSource = client;
12842                        app.adjSourceOom = clientAdj;
12843                        app.adjTarget = cpr.name;
12844                    }
12845                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12846                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12847                    }
12848                }
12849                // If the provider has external (non-framework) process
12850                // dependencies, ensure that its adjustment is at least
12851                // FOREGROUND_APP_ADJ.
12852                if (cpr.hasExternalProcessHandles()) {
12853                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12854                        adj = ProcessList.FOREGROUND_APP_ADJ;
12855                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12856                        app.hidden = false;
12857                        app.keeping = true;
12858                        app.adjType = "provider";
12859                        app.adjTarget = cpr.name;
12860                    }
12861                }
12862            }
12863        }
12864
12865        if (adj == ProcessList.SERVICE_ADJ) {
12866            if (doingAll) {
12867                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12868                mNewNumServiceProcs++;
12869            }
12870            if (app.serviceb) {
12871                adj = ProcessList.SERVICE_B_ADJ;
12872            }
12873        } else {
12874            app.serviceb = false;
12875        }
12876
12877        app.nonStoppingAdj = adj;
12878
12879        if (hasStoppingActivities) {
12880            // Only upgrade adjustment.
12881            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12882                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12883                app.adjType = "stopping";
12884            }
12885        }
12886
12887        app.curRawAdj = adj;
12888
12889        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12890        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12891        if (adj > app.maxAdj) {
12892            adj = app.maxAdj;
12893            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12894                schedGroup = Process.THREAD_GROUP_DEFAULT;
12895            }
12896        }
12897        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12898            app.keeping = true;
12899        }
12900
12901        if (app.hasAboveClient) {
12902            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12903            // then we need to drop its adjustment to be lower than the service's
12904            // in order to honor the request.  We want to drop it by one adjustment
12905            // level...  but there is special meaning applied to various levels so
12906            // we will skip some of them.
12907            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12908                // System process will not get dropped, ever
12909            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12910                adj = ProcessList.VISIBLE_APP_ADJ;
12911            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12912                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12913            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12914                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
12915            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
12916                adj++;
12917            }
12918        }
12919
12920        int importance = app.memImportance;
12921        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
12922            app.curAdj = adj;
12923            app.curSchedGroup = schedGroup;
12924            if (!interesting) {
12925                // For this reporting, if there is not something explicitly
12926                // interesting in this process then we will push it to the
12927                // background importance.
12928                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12929            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12930                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12931            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
12932                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12933            } else if (adj >= ProcessList.HOME_APP_ADJ) {
12934                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12935            } else if (adj >= ProcessList.SERVICE_ADJ) {
12936                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12937            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12938                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
12939            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
12940                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
12941            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
12942                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
12943            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
12944                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
12945            } else {
12946                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
12947            }
12948        }
12949
12950        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
12951        if (foregroundActivities != app.foregroundActivities) {
12952            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
12953        }
12954        if (changes != 0) {
12955            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
12956            app.memImportance = importance;
12957            app.foregroundActivities = foregroundActivities;
12958            int i = mPendingProcessChanges.size()-1;
12959            ProcessChangeItem item = null;
12960            while (i >= 0) {
12961                item = mPendingProcessChanges.get(i);
12962                if (item.pid == app.pid) {
12963                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
12964                    break;
12965                }
12966                i--;
12967            }
12968            if (i < 0) {
12969                // No existing item in pending changes; need a new one.
12970                final int NA = mAvailProcessChanges.size();
12971                if (NA > 0) {
12972                    item = mAvailProcessChanges.remove(NA-1);
12973                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
12974                } else {
12975                    item = new ProcessChangeItem();
12976                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
12977                }
12978                item.changes = 0;
12979                item.pid = app.pid;
12980                item.uid = app.info.uid;
12981                if (mPendingProcessChanges.size() == 0) {
12982                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
12983                            "*** Enqueueing dispatch processes changed!");
12984                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
12985                }
12986                mPendingProcessChanges.add(item);
12987            }
12988            item.changes |= changes;
12989            item.importance = importance;
12990            item.foregroundActivities = foregroundActivities;
12991            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
12992                    + Integer.toHexString(System.identityHashCode(item))
12993                    + " " + app.toShortString() + ": changes=" + item.changes
12994                    + " importance=" + item.importance
12995                    + " foreground=" + item.foregroundActivities
12996                    + " type=" + app.adjType + " source=" + app.adjSource
12997                    + " target=" + app.adjTarget);
12998        }
12999
13000        return app.curRawAdj;
13001    }
13002
13003    /**
13004     * Ask a given process to GC right now.
13005     */
13006    final void performAppGcLocked(ProcessRecord app) {
13007        try {
13008            app.lastRequestedGc = SystemClock.uptimeMillis();
13009            if (app.thread != null) {
13010                if (app.reportLowMemory) {
13011                    app.reportLowMemory = false;
13012                    app.thread.scheduleLowMemory();
13013                } else {
13014                    app.thread.processInBackground();
13015                }
13016            }
13017        } catch (Exception e) {
13018            // whatever.
13019        }
13020    }
13021
13022    /**
13023     * Returns true if things are idle enough to perform GCs.
13024     */
13025    private final boolean canGcNowLocked() {
13026        boolean processingBroadcasts = false;
13027        for (BroadcastQueue q : mBroadcastQueues) {
13028            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13029                processingBroadcasts = true;
13030            }
13031        }
13032        return !processingBroadcasts
13033                && (mSleeping || (mMainStack.mResumedActivity != null &&
13034                        mMainStack.mResumedActivity.idle));
13035    }
13036
13037    /**
13038     * Perform GCs on all processes that are waiting for it, but only
13039     * if things are idle.
13040     */
13041    final void performAppGcsLocked() {
13042        final int N = mProcessesToGc.size();
13043        if (N <= 0) {
13044            return;
13045        }
13046        if (canGcNowLocked()) {
13047            while (mProcessesToGc.size() > 0) {
13048                ProcessRecord proc = mProcessesToGc.remove(0);
13049                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
13050                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13051                            <= SystemClock.uptimeMillis()) {
13052                        // To avoid spamming the system, we will GC processes one
13053                        // at a time, waiting a few seconds between each.
13054                        performAppGcLocked(proc);
13055                        scheduleAppGcsLocked();
13056                        return;
13057                    } else {
13058                        // It hasn't been long enough since we last GCed this
13059                        // process...  put it in the list to wait for its time.
13060                        addProcessToGcListLocked(proc);
13061                        break;
13062                    }
13063                }
13064            }
13065
13066            scheduleAppGcsLocked();
13067        }
13068    }
13069
13070    /**
13071     * If all looks good, perform GCs on all processes waiting for them.
13072     */
13073    final void performAppGcsIfAppropriateLocked() {
13074        if (canGcNowLocked()) {
13075            performAppGcsLocked();
13076            return;
13077        }
13078        // Still not idle, wait some more.
13079        scheduleAppGcsLocked();
13080    }
13081
13082    /**
13083     * Schedule the execution of all pending app GCs.
13084     */
13085    final void scheduleAppGcsLocked() {
13086        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13087
13088        if (mProcessesToGc.size() > 0) {
13089            // Schedule a GC for the time to the next process.
13090            ProcessRecord proc = mProcessesToGc.get(0);
13091            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13092
13093            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13094            long now = SystemClock.uptimeMillis();
13095            if (when < (now+GC_TIMEOUT)) {
13096                when = now + GC_TIMEOUT;
13097            }
13098            mHandler.sendMessageAtTime(msg, when);
13099        }
13100    }
13101
13102    /**
13103     * Add a process to the array of processes waiting to be GCed.  Keeps the
13104     * list in sorted order by the last GC time.  The process can't already be
13105     * on the list.
13106     */
13107    final void addProcessToGcListLocked(ProcessRecord proc) {
13108        boolean added = false;
13109        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13110            if (mProcessesToGc.get(i).lastRequestedGc <
13111                    proc.lastRequestedGc) {
13112                added = true;
13113                mProcessesToGc.add(i+1, proc);
13114                break;
13115            }
13116        }
13117        if (!added) {
13118            mProcessesToGc.add(0, proc);
13119        }
13120    }
13121
13122    /**
13123     * Set up to ask a process to GC itself.  This will either do it
13124     * immediately, or put it on the list of processes to gc the next
13125     * time things are idle.
13126     */
13127    final void scheduleAppGcLocked(ProcessRecord app) {
13128        long now = SystemClock.uptimeMillis();
13129        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13130            return;
13131        }
13132        if (!mProcessesToGc.contains(app)) {
13133            addProcessToGcListLocked(app);
13134            scheduleAppGcsLocked();
13135        }
13136    }
13137
13138    final void checkExcessivePowerUsageLocked(boolean doKills) {
13139        updateCpuStatsNow();
13140
13141        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13142        boolean doWakeKills = doKills;
13143        boolean doCpuKills = doKills;
13144        if (mLastPowerCheckRealtime == 0) {
13145            doWakeKills = false;
13146        }
13147        if (mLastPowerCheckUptime == 0) {
13148            doCpuKills = false;
13149        }
13150        if (stats.isScreenOn()) {
13151            doWakeKills = false;
13152        }
13153        final long curRealtime = SystemClock.elapsedRealtime();
13154        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13155        final long curUptime = SystemClock.uptimeMillis();
13156        final long uptimeSince = curUptime - mLastPowerCheckUptime;
13157        mLastPowerCheckRealtime = curRealtime;
13158        mLastPowerCheckUptime = curUptime;
13159        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13160            doWakeKills = false;
13161        }
13162        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13163            doCpuKills = false;
13164        }
13165        int i = mLruProcesses.size();
13166        while (i > 0) {
13167            i--;
13168            ProcessRecord app = mLruProcesses.get(i);
13169            if (!app.keeping) {
13170                long wtime;
13171                synchronized (stats) {
13172                    wtime = stats.getProcessWakeTime(app.info.uid,
13173                            app.pid, curRealtime);
13174                }
13175                long wtimeUsed = wtime - app.lastWakeTime;
13176                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13177                if (DEBUG_POWER) {
13178                    StringBuilder sb = new StringBuilder(128);
13179                    sb.append("Wake for ");
13180                    app.toShortString(sb);
13181                    sb.append(": over ");
13182                    TimeUtils.formatDuration(realtimeSince, sb);
13183                    sb.append(" used ");
13184                    TimeUtils.formatDuration(wtimeUsed, sb);
13185                    sb.append(" (");
13186                    sb.append((wtimeUsed*100)/realtimeSince);
13187                    sb.append("%)");
13188                    Slog.i(TAG, sb.toString());
13189                    sb.setLength(0);
13190                    sb.append("CPU for ");
13191                    app.toShortString(sb);
13192                    sb.append(": over ");
13193                    TimeUtils.formatDuration(uptimeSince, sb);
13194                    sb.append(" used ");
13195                    TimeUtils.formatDuration(cputimeUsed, sb);
13196                    sb.append(" (");
13197                    sb.append((cputimeUsed*100)/uptimeSince);
13198                    sb.append("%)");
13199                    Slog.i(TAG, sb.toString());
13200                }
13201                // If a process has held a wake lock for more
13202                // than 50% of the time during this period,
13203                // that sounds bad.  Kill!
13204                if (doWakeKills && realtimeSince > 0
13205                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
13206                    synchronized (stats) {
13207                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13208                                realtimeSince, wtimeUsed);
13209                    }
13210                    Slog.w(TAG, "Excessive wake lock in " + app.processName
13211                            + " (pid " + app.pid + "): held " + wtimeUsed
13212                            + " during " + realtimeSince);
13213                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13214                            app.processName, app.setAdj, "excessive wake lock");
13215                    Process.killProcessQuiet(app.pid);
13216                } else if (doCpuKills && uptimeSince > 0
13217                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
13218                    synchronized (stats) {
13219                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13220                                uptimeSince, cputimeUsed);
13221                    }
13222                    Slog.w(TAG, "Excessive CPU in " + app.processName
13223                            + " (pid " + app.pid + "): used " + cputimeUsed
13224                            + " during " + uptimeSince);
13225                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13226                            app.processName, app.setAdj, "excessive cpu");
13227                    Process.killProcessQuiet(app.pid);
13228                } else {
13229                    app.lastWakeTime = wtime;
13230                    app.lastCpuTime = app.curCpuTime;
13231                }
13232            }
13233        }
13234    }
13235
13236    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13237            int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13238        app.hiddenAdj = hiddenAdj;
13239        app.emptyAdj = emptyAdj;
13240
13241        if (app.thread == null) {
13242            return false;
13243        }
13244
13245        final boolean wasKeeping = app.keeping;
13246
13247        boolean success = true;
13248
13249        computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13250
13251        if (app.curRawAdj != app.setRawAdj) {
13252            if (wasKeeping && !app.keeping) {
13253                // This app is no longer something we want to keep.  Note
13254                // its current wake lock time to later know to kill it if
13255                // it is not behaving well.
13256                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13257                synchronized (stats) {
13258                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13259                            app.pid, SystemClock.elapsedRealtime());
13260                }
13261                app.lastCpuTime = app.curCpuTime;
13262            }
13263
13264            app.setRawAdj = app.curRawAdj;
13265        }
13266
13267        if (app.curAdj != app.setAdj) {
13268            if (Process.setOomAdj(app.pid, app.curAdj)) {
13269                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13270                    TAG, "Set " + app.pid + " " + app.processName +
13271                    " adj " + app.curAdj + ": " + app.adjType);
13272                app.setAdj = app.curAdj;
13273            } else {
13274                success = false;
13275                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13276            }
13277        }
13278        if (app.setSchedGroup != app.curSchedGroup) {
13279            app.setSchedGroup = app.curSchedGroup;
13280            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13281                    "Setting process group of " + app.processName
13282                    + " to " + app.curSchedGroup);
13283            if (app.waitingToKill != null &&
13284                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13285                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13286                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13287                        app.processName, app.setAdj, app.waitingToKill);
13288                app.killedBackground = true;
13289                Process.killProcessQuiet(app.pid);
13290                success = false;
13291            } else {
13292                if (true) {
13293                    long oldId = Binder.clearCallingIdentity();
13294                    try {
13295                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13296                    } catch (Exception e) {
13297                        Slog.w(TAG, "Failed setting process group of " + app.pid
13298                                + " to " + app.curSchedGroup);
13299                        e.printStackTrace();
13300                    } finally {
13301                        Binder.restoreCallingIdentity(oldId);
13302                    }
13303                } else {
13304                    if (app.thread != null) {
13305                        try {
13306                            app.thread.setSchedulingGroup(app.curSchedGroup);
13307                        } catch (RemoteException e) {
13308                        }
13309                    }
13310                }
13311            }
13312        }
13313        return success;
13314    }
13315
13316    private final ActivityRecord resumedAppLocked() {
13317        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13318        if (resumedActivity == null || resumedActivity.app == null) {
13319            resumedActivity = mMainStack.mPausingActivity;
13320            if (resumedActivity == null || resumedActivity.app == null) {
13321                resumedActivity = mMainStack.topRunningActivityLocked(null);
13322            }
13323        }
13324        return resumedActivity;
13325    }
13326
13327    final boolean updateOomAdjLocked(ProcessRecord app) {
13328        final ActivityRecord TOP_ACT = resumedAppLocked();
13329        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13330        int curAdj = app.curAdj;
13331        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13332            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13333
13334        mAdjSeq++;
13335
13336        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
13337                TOP_APP, false);
13338        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13339            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13340        if (nowHidden != wasHidden) {
13341            // Changed to/from hidden state, so apps after it in the LRU
13342            // list may also be changed.
13343            updateOomAdjLocked();
13344        }
13345        return success;
13346    }
13347
13348    final void updateOomAdjLocked() {
13349        final ActivityRecord TOP_ACT = resumedAppLocked();
13350        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13351
13352        if (false) {
13353            RuntimeException e = new RuntimeException();
13354            e.fillInStackTrace();
13355            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13356        }
13357
13358        mAdjSeq++;
13359        mNewNumServiceProcs = 0;
13360
13361        // Let's determine how many processes we have running vs.
13362        // how many slots we have for background processes; we may want
13363        // to put multiple processes in a slot of there are enough of
13364        // them.
13365        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13366                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13367        int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
13368        if (emptyFactor < 1) emptyFactor = 1;
13369        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13370        if (hiddenFactor < 1) hiddenFactor = 1;
13371        int stepHidden = 0;
13372        int stepEmpty = 0;
13373        final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13374        final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13375        int numHidden = 0;
13376        int numEmpty = 0;
13377        int numTrimming = 0;
13378
13379        mNumNonHiddenProcs = 0;
13380        mNumHiddenProcs = 0;
13381
13382        // First update the OOM adjustment for each of the
13383        // application processes based on their current state.
13384        int i = mLruProcesses.size();
13385        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13386        int nextHiddenAdj = curHiddenAdj+1;
13387        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13388        int nextEmptyAdj = curEmptyAdj+2;
13389        while (i > 0) {
13390            i--;
13391            ProcessRecord app = mLruProcesses.get(i);
13392            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13393            updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
13394            if (!app.killedBackground) {
13395                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13396                    // This process was assigned as a hidden process...  step the
13397                    // hidden level.
13398                    mNumHiddenProcs++;
13399                    if (curHiddenAdj != nextHiddenAdj) {
13400                        stepHidden++;
13401                        if (stepHidden >= hiddenFactor) {
13402                            stepHidden = 0;
13403                            curHiddenAdj = nextHiddenAdj;
13404                            nextHiddenAdj += 2;
13405                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13406                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13407                            }
13408                        }
13409                    }
13410                    numHidden++;
13411                    if (numHidden > hiddenProcessLimit) {
13412                        Slog.i(TAG, "No longer want " + app.processName
13413                                + " (pid " + app.pid + "): hidden #" + numHidden);
13414                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13415                                app.processName, app.setAdj, "too many background");
13416                        app.killedBackground = true;
13417                        Process.killProcessQuiet(app.pid);
13418                    }
13419                } else {
13420                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13421                        // This process was assigned as an empty process...  step the
13422                        // empty level.
13423                        if (curEmptyAdj != nextEmptyAdj) {
13424                            stepEmpty++;
13425                            if (stepEmpty >= emptyFactor) {
13426                                stepEmpty = 0;
13427                                curEmptyAdj = nextEmptyAdj;
13428                                nextEmptyAdj += 2;
13429                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13430                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13431                                }
13432                            }
13433                        }
13434                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13435                        mNumNonHiddenProcs++;
13436                    }
13437                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13438                        numEmpty++;
13439                        if (numEmpty > emptyProcessLimit) {
13440                            Slog.i(TAG, "No longer want " + app.processName
13441                                    + " (pid " + app.pid + "): empty #" + numEmpty);
13442                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13443                                    app.processName, app.setAdj, "too many background");
13444                            app.killedBackground = true;
13445                            Process.killProcessQuiet(app.pid);
13446                        }
13447                    }
13448                }
13449                if (app.isolated && app.services.size() <= 0) {
13450                    // If this is an isolated process, and there are no
13451                    // services running in it, then the process is no longer
13452                    // needed.  We agressively kill these because we can by
13453                    // definition not re-use the same process again, and it is
13454                    // good to avoid having whatever code was running in them
13455                    // left sitting around after no longer needed.
13456                    Slog.i(TAG, "Isolated process " + app.processName
13457                            + " (pid " + app.pid + ") no longer needed");
13458                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13459                            app.processName, app.setAdj, "isolated not needed");
13460                    app.killedBackground = true;
13461                    Process.killProcessQuiet(app.pid);
13462                }
13463                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13464                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13465                        && !app.killedBackground) {
13466                    numTrimming++;
13467                }
13468            }
13469        }
13470
13471        mNumServiceProcs = mNewNumServiceProcs;
13472
13473        // Now determine the memory trimming level of background processes.
13474        // Unfortunately we need to start at the back of the list to do this
13475        // properly.  We only do this if the number of background apps we
13476        // are managing to keep around is less than half the maximum we desire;
13477        // if we are keeping a good number around, we'll let them use whatever
13478        // memory they want.
13479        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13480                && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13481            final int numHiddenAndEmpty = numHidden + numEmpty;
13482            final int N = mLruProcesses.size();
13483            int factor = numTrimming/3;
13484            int minFactor = 2;
13485            if (mHomeProcess != null) minFactor++;
13486            if (mPreviousProcess != null) minFactor++;
13487            if (factor < minFactor) factor = minFactor;
13488            int step = 0;
13489            int fgTrimLevel;
13490            if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13491                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13492            } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13493                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13494            } else {
13495                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13496            }
13497            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13498            for (i=0; i<N; i++) {
13499                ProcessRecord app = mLruProcesses.get(i);
13500                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13501                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13502                        && !app.killedBackground) {
13503                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13504                        try {
13505                            app.thread.scheduleTrimMemory(curLevel);
13506                        } catch (RemoteException e) {
13507                        }
13508                        if (false) {
13509                            // For now we won't do this; our memory trimming seems
13510                            // to be good enough at this point that destroying
13511                            // activities causes more harm than good.
13512                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13513                                    && app != mHomeProcess && app != mPreviousProcess) {
13514                                // Need to do this on its own message because the stack may not
13515                                // be in a consistent state at this point.
13516                                // For these apps we will also finish their activities
13517                                // to help them free memory.
13518                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13519                            }
13520                        }
13521                    }
13522                    app.trimMemoryLevel = curLevel;
13523                    step++;
13524                    if (step >= factor) {
13525                        step = 0;
13526                        switch (curLevel) {
13527                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13528                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13529                                break;
13530                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13531                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13532                                break;
13533                        }
13534                    }
13535                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13536                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13537                            && app.thread != null) {
13538                        try {
13539                            app.thread.scheduleTrimMemory(
13540                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13541                        } catch (RemoteException e) {
13542                        }
13543                    }
13544                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13545                } else {
13546                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13547                            && app.pendingUiClean) {
13548                        // If this application is now in the background and it
13549                        // had done UI, then give it the special trim level to
13550                        // have it free UI resources.
13551                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13552                        if (app.trimMemoryLevel < level && app.thread != null) {
13553                            try {
13554                                app.thread.scheduleTrimMemory(level);
13555                            } catch (RemoteException e) {
13556                            }
13557                        }
13558                        app.pendingUiClean = false;
13559                    }
13560                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13561                        try {
13562                            app.thread.scheduleTrimMemory(fgTrimLevel);
13563                        } catch (RemoteException e) {
13564                        }
13565                    }
13566                    app.trimMemoryLevel = fgTrimLevel;
13567                }
13568            }
13569        } else {
13570            final int N = mLruProcesses.size();
13571            for (i=0; i<N; i++) {
13572                ProcessRecord app = mLruProcesses.get(i);
13573                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13574                        && app.pendingUiClean) {
13575                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13576                            && app.thread != null) {
13577                        try {
13578                            app.thread.scheduleTrimMemory(
13579                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13580                        } catch (RemoteException e) {
13581                        }
13582                    }
13583                    app.pendingUiClean = false;
13584                }
13585                app.trimMemoryLevel = 0;
13586            }
13587        }
13588
13589        if (mAlwaysFinishActivities) {
13590            // Need to do this on its own message because the stack may not
13591            // be in a consistent state at this point.
13592            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13593        }
13594    }
13595
13596    final void trimApplications() {
13597        synchronized (this) {
13598            int i;
13599
13600            // First remove any unused application processes whose package
13601            // has been removed.
13602            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13603                final ProcessRecord app = mRemovedProcesses.get(i);
13604                if (app.activities.size() == 0
13605                        && app.curReceiver == null && app.services.size() == 0) {
13606                    Slog.i(
13607                        TAG, "Exiting empty application process "
13608                        + app.processName + " ("
13609                        + (app.thread != null ? app.thread.asBinder() : null)
13610                        + ")\n");
13611                    if (app.pid > 0 && app.pid != MY_PID) {
13612                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13613                                app.processName, app.setAdj, "empty");
13614                        Process.killProcessQuiet(app.pid);
13615                    } else {
13616                        try {
13617                            app.thread.scheduleExit();
13618                        } catch (Exception e) {
13619                            // Ignore exceptions.
13620                        }
13621                    }
13622                    cleanUpApplicationRecordLocked(app, false, true, -1);
13623                    mRemovedProcesses.remove(i);
13624
13625                    if (app.persistent) {
13626                        if (app.persistent) {
13627                            addAppLocked(app.info, false);
13628                        }
13629                    }
13630                }
13631            }
13632
13633            // Now update the oom adj for all processes.
13634            updateOomAdjLocked();
13635        }
13636    }
13637
13638    /** This method sends the specified signal to each of the persistent apps */
13639    public void signalPersistentProcesses(int sig) throws RemoteException {
13640        if (sig != Process.SIGNAL_USR1) {
13641            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13642        }
13643
13644        synchronized (this) {
13645            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13646                    != PackageManager.PERMISSION_GRANTED) {
13647                throw new SecurityException("Requires permission "
13648                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13649            }
13650
13651            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13652                ProcessRecord r = mLruProcesses.get(i);
13653                if (r.thread != null && r.persistent) {
13654                    Process.sendSignal(r.pid, sig);
13655                }
13656            }
13657        }
13658    }
13659
13660    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13661        if (proc == null || proc == mProfileProc) {
13662            proc = mProfileProc;
13663            path = mProfileFile;
13664            profileType = mProfileType;
13665            clearProfilerLocked();
13666        }
13667        if (proc == null) {
13668            return;
13669        }
13670        try {
13671            proc.thread.profilerControl(false, path, null, profileType);
13672        } catch (RemoteException e) {
13673            throw new IllegalStateException("Process disappeared");
13674        }
13675    }
13676
13677    private void clearProfilerLocked() {
13678        if (mProfileFd != null) {
13679            try {
13680                mProfileFd.close();
13681            } catch (IOException e) {
13682            }
13683        }
13684        mProfileApp = null;
13685        mProfileProc = null;
13686        mProfileFile = null;
13687        mProfileType = 0;
13688        mAutoStopProfiler = false;
13689    }
13690
13691    public boolean profileControl(String process, boolean start,
13692            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13693
13694        try {
13695            synchronized (this) {
13696                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13697                // its own permission.
13698                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13699                        != PackageManager.PERMISSION_GRANTED) {
13700                    throw new SecurityException("Requires permission "
13701                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13702                }
13703
13704                if (start && fd == null) {
13705                    throw new IllegalArgumentException("null fd");
13706                }
13707
13708                ProcessRecord proc = null;
13709                if (process != null) {
13710                    try {
13711                        int pid = Integer.parseInt(process);
13712                        synchronized (mPidsSelfLocked) {
13713                            proc = mPidsSelfLocked.get(pid);
13714                        }
13715                    } catch (NumberFormatException e) {
13716                    }
13717
13718                    if (proc == null) {
13719                        HashMap<String, SparseArray<ProcessRecord>> all
13720                                = mProcessNames.getMap();
13721                        SparseArray<ProcessRecord> procs = all.get(process);
13722                        if (procs != null && procs.size() > 0) {
13723                            proc = procs.valueAt(0);
13724                        }
13725                    }
13726                }
13727
13728                if (start && (proc == null || proc.thread == null)) {
13729                    throw new IllegalArgumentException("Unknown process: " + process);
13730                }
13731
13732                if (start) {
13733                    stopProfilerLocked(null, null, 0);
13734                    setProfileApp(proc.info, proc.processName, path, fd, false);
13735                    mProfileProc = proc;
13736                    mProfileType = profileType;
13737                    try {
13738                        fd = fd.dup();
13739                    } catch (IOException e) {
13740                        fd = null;
13741                    }
13742                    proc.thread.profilerControl(start, path, fd, profileType);
13743                    fd = null;
13744                    mProfileFd = null;
13745                } else {
13746                    stopProfilerLocked(proc, path, profileType);
13747                    if (fd != null) {
13748                        try {
13749                            fd.close();
13750                        } catch (IOException e) {
13751                        }
13752                    }
13753                }
13754
13755                return true;
13756            }
13757        } catch (RemoteException e) {
13758            throw new IllegalStateException("Process disappeared");
13759        } finally {
13760            if (fd != null) {
13761                try {
13762                    fd.close();
13763                } catch (IOException e) {
13764                }
13765            }
13766        }
13767    }
13768
13769    public boolean dumpHeap(String process, boolean managed,
13770            String path, ParcelFileDescriptor fd) throws RemoteException {
13771
13772        try {
13773            synchronized (this) {
13774                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13775                // its own permission (same as profileControl).
13776                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13777                        != PackageManager.PERMISSION_GRANTED) {
13778                    throw new SecurityException("Requires permission "
13779                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13780                }
13781
13782                if (fd == null) {
13783                    throw new IllegalArgumentException("null fd");
13784                }
13785
13786                ProcessRecord proc = null;
13787                try {
13788                    int pid = Integer.parseInt(process);
13789                    synchronized (mPidsSelfLocked) {
13790                        proc = mPidsSelfLocked.get(pid);
13791                    }
13792                } catch (NumberFormatException e) {
13793                }
13794
13795                if (proc == null) {
13796                    HashMap<String, SparseArray<ProcessRecord>> all
13797                            = mProcessNames.getMap();
13798                    SparseArray<ProcessRecord> procs = all.get(process);
13799                    if (procs != null && procs.size() > 0) {
13800                        proc = procs.valueAt(0);
13801                    }
13802                }
13803
13804                if (proc == null || proc.thread == null) {
13805                    throw new IllegalArgumentException("Unknown process: " + process);
13806                }
13807
13808                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13809                if (!isDebuggable) {
13810                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13811                        throw new SecurityException("Process not debuggable: " + proc);
13812                    }
13813                }
13814
13815                proc.thread.dumpHeap(managed, path, fd);
13816                fd = null;
13817                return true;
13818            }
13819        } catch (RemoteException e) {
13820            throw new IllegalStateException("Process disappeared");
13821        } finally {
13822            if (fd != null) {
13823                try {
13824                    fd.close();
13825                } catch (IOException e) {
13826                }
13827            }
13828        }
13829    }
13830
13831    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13832    public void monitor() {
13833        synchronized (this) { }
13834    }
13835
13836    void onCoreSettingsChange(Bundle settings) {
13837        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13838            ProcessRecord processRecord = mLruProcesses.get(i);
13839            try {
13840                if (processRecord.thread != null) {
13841                    processRecord.thread.setCoreSettings(settings);
13842                }
13843            } catch (RemoteException re) {
13844                /* ignore */
13845            }
13846        }
13847    }
13848
13849    // Multi-user methods
13850
13851    @Override
13852    public boolean switchUser(int userId) {
13853        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13854                != PackageManager.PERMISSION_GRANTED) {
13855            String msg = "Permission Denial: switchUser() from pid="
13856                    + Binder.getCallingPid()
13857                    + ", uid=" + Binder.getCallingUid()
13858                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13859            Slog.w(TAG, msg);
13860            throw new SecurityException(msg);
13861        }
13862        synchronized (this) {
13863            if (mCurrentUserId == userId) {
13864                return true;
13865            }
13866
13867            // If the user we are switching to is not currently started, then
13868            // we need to start it now.
13869            if (mStartedUsers.get(userId) == null) {
13870                mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
13871            }
13872
13873            mCurrentUserId = userId;
13874            Integer userIdInt = Integer.valueOf(userId);
13875            mUserLru.remove(userIdInt);
13876            mUserLru.add(userIdInt);
13877            boolean haveActivities = mMainStack.switchUser(userId);
13878            if (!haveActivities) {
13879                startHomeActivityLocked(userId, mStartedUsers.get(userId));
13880            }
13881        }
13882
13883        long ident = Binder.clearCallingIdentity();
13884        try {
13885            // Inform of user switch
13886            Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
13887            addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13888            mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL,
13889                    android.Manifest.permission.MANAGE_USERS);
13890        } finally {
13891            Binder.restoreCallingIdentity(ident);
13892        }
13893
13894        return true;
13895    }
13896
13897    void finishUserSwitch(UserStartedState uss) {
13898        synchronized (this) {
13899            if (uss.mState == UserStartedState.STATE_BOOTING
13900                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
13901                uss.mState = UserStartedState.STATE_RUNNING;
13902                final int userId = uss.mHandle.getIdentifier();
13903                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
13904                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13905                broadcastIntentLocked(null, null, intent,
13906                        null, null, 0, null, null,
13907                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
13908                        false, false, MY_PID, Process.SYSTEM_UID, userId);
13909            }
13910        }
13911    }
13912
13913    @Override
13914    public int stopUser(final int userId, final IStopUserCallback callback) {
13915        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13916                != PackageManager.PERMISSION_GRANTED) {
13917            String msg = "Permission Denial: switchUser() from pid="
13918                    + Binder.getCallingPid()
13919                    + ", uid=" + Binder.getCallingUid()
13920                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13921            Slog.w(TAG, msg);
13922            throw new SecurityException(msg);
13923        }
13924        if (userId <= 0) {
13925            throw new IllegalArgumentException("Can't stop primary user " + userId);
13926        }
13927        synchronized (this) {
13928            if (mCurrentUserId == userId) {
13929                return ActivityManager.USER_OP_IS_CURRENT;
13930            }
13931
13932            final UserStartedState uss = mStartedUsers.get(userId);
13933            if (uss == null) {
13934                // User is not started, nothing to do...  but we do need to
13935                // callback if requested.
13936                if (callback != null) {
13937                    mHandler.post(new Runnable() {
13938                        @Override
13939                        public void run() {
13940                            try {
13941                                callback.userStopped(userId);
13942                            } catch (RemoteException e) {
13943                            }
13944                        }
13945                    });
13946                }
13947                return ActivityManager.USER_OP_SUCCESS;
13948            }
13949
13950            if (callback != null) {
13951                uss.mStopCallbacks.add(callback);
13952            }
13953
13954            if (uss.mState != UserStartedState.STATE_STOPPING) {
13955                uss.mState = UserStartedState.STATE_STOPPING;
13956
13957                long ident = Binder.clearCallingIdentity();
13958                try {
13959                    // Inform of user switch
13960                    Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13961                    final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() {
13962                        @Override
13963                        public void performReceive(Intent intent, int resultCode, String data,
13964                                Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
13965                            finishUserStop(uss);
13966                        }
13967                    };
13968                    broadcastIntentLocked(null, null, intent,
13969                            null, resultReceiver, 0, null, null, null,
13970                            true, false, MY_PID, Process.SYSTEM_UID, userId);
13971                } finally {
13972                    Binder.restoreCallingIdentity(ident);
13973                }
13974            }
13975        }
13976
13977        return ActivityManager.USER_OP_SUCCESS;
13978    }
13979
13980    void finishUserStop(UserStartedState uss) {
13981        final int userId = uss.mHandle.getIdentifier();
13982        boolean stopped;
13983        ArrayList<IStopUserCallback> callbacks;
13984        synchronized (this) {
13985            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
13986            if (uss.mState != UserStartedState.STATE_STOPPING
13987                    || mStartedUsers.get(userId) != uss) {
13988                stopped = false;
13989            } else {
13990                stopped = true;
13991                // User can no longer run.
13992                mStartedUsers.remove(userId);
13993
13994                // Clean up all state and processes associated with the user.
13995                // Kill all the processes for the user.
13996                forceStopUserLocked(userId);
13997            }
13998        }
13999
14000        for (int i=0; i<callbacks.size(); i++) {
14001            try {
14002                if (stopped) callbacks.get(i).userStopped(userId);
14003                else callbacks.get(i).userStopAborted(userId);
14004            } catch (RemoteException e) {
14005            }
14006        }
14007    }
14008
14009    @Override
14010    public UserInfo getCurrentUser() {
14011        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14012                != PackageManager.PERMISSION_GRANTED) {
14013            String msg = "Permission Denial: getCurrentUser() from pid="
14014                    + Binder.getCallingPid()
14015                    + ", uid=" + Binder.getCallingUid()
14016                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14017            Slog.w(TAG, msg);
14018            throw new SecurityException(msg);
14019        }
14020        synchronized (this) {
14021            return getUserManager().getUserInfo(mCurrentUserId);
14022        }
14023    }
14024
14025    @Override
14026    public boolean isUserRunning(int userId) {
14027        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14028                != PackageManager.PERMISSION_GRANTED) {
14029            String msg = "Permission Denial: isUserRunning() from pid="
14030                    + Binder.getCallingPid()
14031                    + ", uid=" + Binder.getCallingUid()
14032                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14033            Slog.w(TAG, msg);
14034            throw new SecurityException(msg);
14035        }
14036        synchronized (this) {
14037            UserStartedState state = mStartedUsers.get(userId);
14038            return state != null && state.mState != UserStartedState.STATE_STOPPING;
14039        }
14040    }
14041
14042    private boolean userExists(int userId) {
14043        UserInfo user = getUserManager().getUserInfo(userId);
14044        return user != null;
14045    }
14046
14047    UserManager getUserManager() {
14048        if (mUserManager == null) {
14049            mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
14050        }
14051        return mUserManager;
14052    }
14053
14054    private void checkValidCaller(int uid, int userId) {
14055        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
14056
14057        throw new SecurityException("Caller uid=" + uid
14058                + " is not privileged to communicate with user=" + userId);
14059    }
14060
14061    private int applyUserId(int uid, int userId) {
14062        return UserHandle.getUid(userId, uid);
14063    }
14064
14065    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
14066        if (info == null) return null;
14067        ApplicationInfo newInfo = new ApplicationInfo(info);
14068        newInfo.uid = applyUserId(info.uid, userId);
14069        newInfo.dataDir = USER_DATA_DIR + userId + "/"
14070                + info.packageName;
14071        return newInfo;
14072    }
14073
14074    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
14075        if (aInfo == null
14076                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
14077            return aInfo;
14078        }
14079
14080        ActivityInfo info = new ActivityInfo(aInfo);
14081        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
14082        return info;
14083    }
14084}
14085