ActivityManagerService.java revision 74ee8652e02fc94901177214fc9370659732c921
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 = new ProviderMap();
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
1515        File dataDir = Environment.getDataDirectory();
1516        File systemDir = new File(dataDir, "system");
1517        systemDir.mkdirs();
1518        mBatteryStatsService = new BatteryStatsService(new File(
1519                systemDir, "batterystats.bin").toString());
1520        mBatteryStatsService.getActiveStatistics().readLocked();
1521        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1522        mOnBattery = DEBUG_POWER ? true
1523                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1524        mBatteryStatsService.getActiveStatistics().setCallback(this);
1525
1526        mUsageStatsService = new UsageStatsService(new File(
1527                systemDir, "usagestats").toString());
1528        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1529
1530        // User 0 is the first and only user that runs at boot.
1531        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1532        mUserLru.add(Integer.valueOf(0));
1533
1534        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1535            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1536
1537        mConfiguration.setToDefaults();
1538        mConfiguration.setLocale(Locale.getDefault());
1539
1540        mConfigurationSeq = mConfiguration.seq = 1;
1541        mProcessStats.init();
1542
1543        mCompatModePackages = new CompatModePackages(this, systemDir);
1544
1545        // Add ourself to the Watchdog monitors.
1546        Watchdog.getInstance().addMonitor(this);
1547
1548        mProcessStatsThread = new Thread("ProcessStats") {
1549            public void run() {
1550                while (true) {
1551                    try {
1552                        try {
1553                            synchronized(this) {
1554                                final long now = SystemClock.uptimeMillis();
1555                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1556                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1557                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1558                                //        + ", write delay=" + nextWriteDelay);
1559                                if (nextWriteDelay < nextCpuDelay) {
1560                                    nextCpuDelay = nextWriteDelay;
1561                                }
1562                                if (nextCpuDelay > 0) {
1563                                    mProcessStatsMutexFree.set(true);
1564                                    this.wait(nextCpuDelay);
1565                                }
1566                            }
1567                        } catch (InterruptedException e) {
1568                        }
1569                        updateCpuStatsNow();
1570                    } catch (Exception e) {
1571                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1572                    }
1573                }
1574            }
1575        };
1576        mProcessStatsThread.start();
1577    }
1578
1579    @Override
1580    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1581            throws RemoteException {
1582        if (code == SYSPROPS_TRANSACTION) {
1583            // We need to tell all apps about the system property change.
1584            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1585            synchronized(this) {
1586                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1587                    final int NA = apps.size();
1588                    for (int ia=0; ia<NA; ia++) {
1589                        ProcessRecord app = apps.valueAt(ia);
1590                        if (app.thread != null) {
1591                            procs.add(app.thread.asBinder());
1592                        }
1593                    }
1594                }
1595            }
1596
1597            int N = procs.size();
1598            for (int i=0; i<N; i++) {
1599                Parcel data2 = Parcel.obtain();
1600                try {
1601                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1602                } catch (RemoteException e) {
1603                }
1604                data2.recycle();
1605            }
1606        }
1607        try {
1608            return super.onTransact(code, data, reply, flags);
1609        } catch (RuntimeException e) {
1610            // The activity manager only throws security exceptions, so let's
1611            // log all others.
1612            if (!(e instanceof SecurityException)) {
1613                Slog.e(TAG, "Activity Manager Crash", e);
1614            }
1615            throw e;
1616        }
1617    }
1618
1619    void updateCpuStats() {
1620        final long now = SystemClock.uptimeMillis();
1621        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1622            return;
1623        }
1624        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1625            synchronized (mProcessStatsThread) {
1626                mProcessStatsThread.notify();
1627            }
1628        }
1629    }
1630
1631    void updateCpuStatsNow() {
1632        synchronized (mProcessStatsThread) {
1633            mProcessStatsMutexFree.set(false);
1634            final long now = SystemClock.uptimeMillis();
1635            boolean haveNewCpuStats = false;
1636
1637            if (MONITOR_CPU_USAGE &&
1638                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1639                mLastCpuTime.set(now);
1640                haveNewCpuStats = true;
1641                mProcessStats.update();
1642                //Slog.i(TAG, mProcessStats.printCurrentState());
1643                //Slog.i(TAG, "Total CPU usage: "
1644                //        + mProcessStats.getTotalCpuPercent() + "%");
1645
1646                // Slog the cpu usage if the property is set.
1647                if ("true".equals(SystemProperties.get("events.cpu"))) {
1648                    int user = mProcessStats.getLastUserTime();
1649                    int system = mProcessStats.getLastSystemTime();
1650                    int iowait = mProcessStats.getLastIoWaitTime();
1651                    int irq = mProcessStats.getLastIrqTime();
1652                    int softIrq = mProcessStats.getLastSoftIrqTime();
1653                    int idle = mProcessStats.getLastIdleTime();
1654
1655                    int total = user + system + iowait + irq + softIrq + idle;
1656                    if (total == 0) total = 1;
1657
1658                    EventLog.writeEvent(EventLogTags.CPU,
1659                            ((user+system+iowait+irq+softIrq) * 100) / total,
1660                            (user * 100) / total,
1661                            (system * 100) / total,
1662                            (iowait * 100) / total,
1663                            (irq * 100) / total,
1664                            (softIrq * 100) / total);
1665                }
1666            }
1667
1668            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1669            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1670            synchronized(bstats) {
1671                synchronized(mPidsSelfLocked) {
1672                    if (haveNewCpuStats) {
1673                        if (mOnBattery) {
1674                            int perc = bstats.startAddingCpuLocked();
1675                            int totalUTime = 0;
1676                            int totalSTime = 0;
1677                            final int N = mProcessStats.countStats();
1678                            for (int i=0; i<N; i++) {
1679                                ProcessStats.Stats st = mProcessStats.getStats(i);
1680                                if (!st.working) {
1681                                    continue;
1682                                }
1683                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1684                                int otherUTime = (st.rel_utime*perc)/100;
1685                                int otherSTime = (st.rel_stime*perc)/100;
1686                                totalUTime += otherUTime;
1687                                totalSTime += otherSTime;
1688                                if (pr != null) {
1689                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1690                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1691                                            st.rel_stime-otherSTime);
1692                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1693                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1694                                } else {
1695                                    BatteryStatsImpl.Uid.Proc ps =
1696                                            bstats.getProcessStatsLocked(st.name, st.pid);
1697                                    if (ps != null) {
1698                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1699                                                st.rel_stime-otherSTime);
1700                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1701                                    }
1702                                }
1703                            }
1704                            bstats.finishAddingCpuLocked(perc, totalUTime,
1705                                    totalSTime, cpuSpeedTimes);
1706                        }
1707                    }
1708                }
1709
1710                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1711                    mLastWriteTime = now;
1712                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1713                }
1714            }
1715        }
1716    }
1717
1718    @Override
1719    public void batteryNeedsCpuUpdate() {
1720        updateCpuStatsNow();
1721    }
1722
1723    @Override
1724    public void batteryPowerChanged(boolean onBattery) {
1725        // When plugging in, update the CPU stats first before changing
1726        // the plug state.
1727        updateCpuStatsNow();
1728        synchronized (this) {
1729            synchronized(mPidsSelfLocked) {
1730                mOnBattery = DEBUG_POWER ? true : onBattery;
1731            }
1732        }
1733    }
1734
1735    /**
1736     * Initialize the application bind args. These are passed to each
1737     * process when the bindApplication() IPC is sent to the process. They're
1738     * lazily setup to make sure the services are running when they're asked for.
1739     */
1740    private HashMap<String, IBinder> getCommonServicesLocked() {
1741        if (mAppBindArgs == null) {
1742            mAppBindArgs = new HashMap<String, IBinder>();
1743
1744            // Setup the application init args
1745            mAppBindArgs.put("package", ServiceManager.getService("package"));
1746            mAppBindArgs.put("window", ServiceManager.getService("window"));
1747            mAppBindArgs.put(Context.ALARM_SERVICE,
1748                    ServiceManager.getService(Context.ALARM_SERVICE));
1749        }
1750        return mAppBindArgs;
1751    }
1752
1753    final void setFocusedActivityLocked(ActivityRecord r) {
1754        if (mFocusedActivity != r) {
1755            mFocusedActivity = r;
1756            if (r != null) {
1757                mWindowManager.setFocusedApp(r.appToken, true);
1758            }
1759        }
1760    }
1761
1762    private final void updateLruProcessInternalLocked(ProcessRecord app,
1763            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1764        // put it on the LRU to keep track of when it should be exited.
1765        int lrui = mLruProcesses.indexOf(app);
1766        if (lrui >= 0) mLruProcesses.remove(lrui);
1767
1768        int i = mLruProcesses.size()-1;
1769        int skipTop = 0;
1770
1771        app.lruSeq = mLruSeq;
1772
1773        // compute the new weight for this process.
1774        if (updateActivityTime) {
1775            app.lastActivityTime = SystemClock.uptimeMillis();
1776        }
1777        if (app.activities.size() > 0) {
1778            // If this process has activities, we more strongly want to keep
1779            // it around.
1780            app.lruWeight = app.lastActivityTime;
1781        } else if (app.pubProviders.size() > 0) {
1782            // If this process contains content providers, we want to keep
1783            // it a little more strongly.
1784            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1785            // Also don't let it kick out the first few "real" hidden processes.
1786            skipTop = ProcessList.MIN_HIDDEN_APPS;
1787        } else {
1788            // If this process doesn't have activities, we less strongly
1789            // want to keep it around, and generally want to avoid getting
1790            // in front of any very recently used activities.
1791            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1792            // Also don't let it kick out the first few "real" hidden processes.
1793            skipTop = ProcessList.MIN_HIDDEN_APPS;
1794        }
1795
1796        while (i >= 0) {
1797            ProcessRecord p = mLruProcesses.get(i);
1798            // If this app shouldn't be in front of the first N background
1799            // apps, then skip over that many that are currently hidden.
1800            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1801                skipTop--;
1802            }
1803            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1804                mLruProcesses.add(i+1, app);
1805                break;
1806            }
1807            i--;
1808        }
1809        if (i < 0) {
1810            mLruProcesses.add(0, app);
1811        }
1812
1813        // If the app is currently using a content provider or service,
1814        // bump those processes as well.
1815        if (app.connections.size() > 0) {
1816            for (ConnectionRecord cr : app.connections) {
1817                if (cr.binding != null && cr.binding.service != null
1818                        && cr.binding.service.app != null
1819                        && cr.binding.service.app.lruSeq != mLruSeq) {
1820                    updateLruProcessInternalLocked(cr.binding.service.app, false,
1821                            updateActivityTime, i+1);
1822                }
1823            }
1824        }
1825        for (int j=app.conProviders.size()-1; j>=0; j--) {
1826            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1827            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1828                updateLruProcessInternalLocked(cpr.proc, false,
1829                        updateActivityTime, i+1);
1830            }
1831        }
1832
1833        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1834        if (oomAdj) {
1835            updateOomAdjLocked();
1836        }
1837    }
1838
1839    final void updateLruProcessLocked(ProcessRecord app,
1840            boolean oomAdj, boolean updateActivityTime) {
1841        mLruSeq++;
1842        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1843    }
1844
1845    final ProcessRecord getProcessRecordLocked(
1846            String processName, int uid) {
1847        if (uid == Process.SYSTEM_UID) {
1848            // The system gets to run in any process.  If there are multiple
1849            // processes with the same uid, just pick the first (this
1850            // should never happen).
1851            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1852                    processName);
1853            if (procs == null) return null;
1854            final int N = procs.size();
1855            for (int i = 0; i < N; i++) {
1856                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1857            }
1858        }
1859        ProcessRecord proc = mProcessNames.get(processName, uid);
1860        return proc;
1861    }
1862
1863    void ensurePackageDexOpt(String packageName) {
1864        IPackageManager pm = AppGlobals.getPackageManager();
1865        try {
1866            if (pm.performDexOpt(packageName)) {
1867                mDidDexOpt = true;
1868            }
1869        } catch (RemoteException e) {
1870        }
1871    }
1872
1873    boolean isNextTransitionForward() {
1874        int transit = mWindowManager.getPendingAppTransition();
1875        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1876                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1877                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1878    }
1879
1880    final ProcessRecord startProcessLocked(String processName,
1881            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1882            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1883            boolean isolated) {
1884        ProcessRecord app;
1885        if (!isolated) {
1886            app = getProcessRecordLocked(processName, info.uid);
1887        } else {
1888            // If this is an isolated process, it can't re-use an existing process.
1889            app = null;
1890        }
1891        // We don't have to do anything more if:
1892        // (1) There is an existing application record; and
1893        // (2) The caller doesn't think it is dead, OR there is no thread
1894        //     object attached to it so we know it couldn't have crashed; and
1895        // (3) There is a pid assigned to it, so it is either starting or
1896        //     already running.
1897        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1898                + " app=" + app + " knownToBeDead=" + knownToBeDead
1899                + " thread=" + (app != null ? app.thread : null)
1900                + " pid=" + (app != null ? app.pid : -1));
1901        if (app != null && app.pid > 0) {
1902            if (!knownToBeDead || app.thread == null) {
1903                // We already have the app running, or are waiting for it to
1904                // come up (we have a pid but not yet its thread), so keep it.
1905                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1906                // If this is a new package in the process, add the package to the list
1907                app.addPackage(info.packageName);
1908                return app;
1909            } else {
1910                // An application record is attached to a previous process,
1911                // clean it up now.
1912                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1913                handleAppDiedLocked(app, true, true);
1914            }
1915        }
1916
1917        String hostingNameStr = hostingName != null
1918                ? hostingName.flattenToShortString() : null;
1919
1920        if (!isolated) {
1921            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1922                // If we are in the background, then check to see if this process
1923                // is bad.  If so, we will just silently fail.
1924                if (mBadProcesses.get(info.processName, info.uid) != null) {
1925                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1926                            + "/" + info.processName);
1927                    return null;
1928                }
1929            } else {
1930                // When the user is explicitly starting a process, then clear its
1931                // crash count so that we won't make it bad until they see at
1932                // least one crash dialog again, and make the process good again
1933                // if it had been bad.
1934                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1935                        + "/" + info.processName);
1936                mProcessCrashTimes.remove(info.processName, info.uid);
1937                if (mBadProcesses.get(info.processName, info.uid) != null) {
1938                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1939                            info.processName);
1940                    mBadProcesses.remove(info.processName, info.uid);
1941                    if (app != null) {
1942                        app.bad = false;
1943                    }
1944                }
1945            }
1946        }
1947
1948        if (app == null) {
1949            app = newProcessRecordLocked(null, info, processName, isolated);
1950            if (app == null) {
1951                Slog.w(TAG, "Failed making new process record for "
1952                        + processName + "/" + info.uid + " isolated=" + isolated);
1953                return null;
1954            }
1955            mProcessNames.put(processName, app.uid, app);
1956            if (isolated) {
1957                mIsolatedProcesses.put(app.uid, app);
1958            }
1959        } else {
1960            // If this is a new package in the process, add the package to the list
1961            app.addPackage(info.packageName);
1962        }
1963
1964        // If the system is not ready yet, then hold off on starting this
1965        // process until it is.
1966        if (!mProcessesReady
1967                && !isAllowedWhileBooting(info)
1968                && !allowWhileBooting) {
1969            if (!mProcessesOnHold.contains(app)) {
1970                mProcessesOnHold.add(app);
1971            }
1972            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1973            return app;
1974        }
1975
1976        startProcessLocked(app, hostingType, hostingNameStr);
1977        return (app.pid != 0) ? app : null;
1978    }
1979
1980    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1981        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1982    }
1983
1984    private final void startProcessLocked(ProcessRecord app,
1985            String hostingType, String hostingNameStr) {
1986        if (app.pid > 0 && app.pid != MY_PID) {
1987            synchronized (mPidsSelfLocked) {
1988                mPidsSelfLocked.remove(app.pid);
1989                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1990            }
1991            app.setPid(0);
1992        }
1993
1994        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1995                "startProcessLocked removing on hold: " + app);
1996        mProcessesOnHold.remove(app);
1997
1998        updateCpuStats();
1999
2000        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2001        mProcDeaths[0] = 0;
2002
2003        try {
2004            int uid = app.uid;
2005
2006            int[] gids = null;
2007            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2008            if (!app.isolated) {
2009                try {
2010                    final PackageManager pm = mContext.getPackageManager();
2011                    gids = pm.getPackageGids(app.info.packageName);
2012
2013                    if (Environment.isExternalStorageEmulated()) {
2014                        if (pm.checkPermission(
2015                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2016                                app.info.packageName) == PERMISSION_GRANTED) {
2017                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2018                        } else {
2019                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2020                        }
2021                    }
2022                } catch (PackageManager.NameNotFoundException e) {
2023                    Slog.w(TAG, "Unable to retrieve gids", e);
2024                }
2025            }
2026            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2027                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2028                        && mTopComponent != null
2029                        && app.processName.equals(mTopComponent.getPackageName())) {
2030                    uid = 0;
2031                }
2032                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2033                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2034                    uid = 0;
2035                }
2036            }
2037            int debugFlags = 0;
2038            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2039                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2040                // Also turn on CheckJNI for debuggable apps. It's quite
2041                // awkward to turn on otherwise.
2042                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2043            }
2044            // Run the app in safe mode if its manifest requests so or the
2045            // system is booted in safe mode.
2046            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2047                Zygote.systemInSafeMode == true) {
2048                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2049            }
2050            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2051                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2052            }
2053            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2054                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2055            }
2056            if ("1".equals(SystemProperties.get("debug.assert"))) {
2057                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2058            }
2059
2060            // Start the process.  It will either succeed and return a result containing
2061            // the PID of the new process, or else throw a RuntimeException.
2062            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2063                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2064                    app.info.targetSdkVersion, null, null);
2065
2066            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2067            synchronized (bs) {
2068                if (bs.isOnBattery()) {
2069                    app.batteryStats.incStartsLocked();
2070                }
2071            }
2072
2073            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2074                    app.processName, hostingType,
2075                    hostingNameStr != null ? hostingNameStr : "");
2076
2077            if (app.persistent) {
2078                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2079            }
2080
2081            StringBuilder buf = mStringBuilder;
2082            buf.setLength(0);
2083            buf.append("Start proc ");
2084            buf.append(app.processName);
2085            buf.append(" for ");
2086            buf.append(hostingType);
2087            if (hostingNameStr != null) {
2088                buf.append(" ");
2089                buf.append(hostingNameStr);
2090            }
2091            buf.append(": pid=");
2092            buf.append(startResult.pid);
2093            buf.append(" uid=");
2094            buf.append(uid);
2095            buf.append(" gids={");
2096            if (gids != null) {
2097                for (int gi=0; gi<gids.length; gi++) {
2098                    if (gi != 0) buf.append(", ");
2099                    buf.append(gids[gi]);
2100
2101                }
2102            }
2103            buf.append("}");
2104            Slog.i(TAG, buf.toString());
2105            app.setPid(startResult.pid);
2106            app.usingWrapper = startResult.usingWrapper;
2107            app.removed = false;
2108            synchronized (mPidsSelfLocked) {
2109                this.mPidsSelfLocked.put(startResult.pid, app);
2110                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2111                msg.obj = app;
2112                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2113                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2114            }
2115        } catch (RuntimeException e) {
2116            // XXX do better error recovery.
2117            app.setPid(0);
2118            Slog.e(TAG, "Failure starting process " + app.processName, e);
2119        }
2120    }
2121
2122    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2123        if (resumed) {
2124            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2125        } else {
2126            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2127        }
2128    }
2129
2130    boolean startHomeActivityLocked(int userId, UserStartedState startingUser) {
2131        if (mHeadless) {
2132            // Added because none of the other calls to ensureBootCompleted seem to fire
2133            // when running headless.
2134            ensureBootCompleted();
2135            return false;
2136        }
2137
2138        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2139                && mTopAction == null) {
2140            // We are running in factory test mode, but unable to find
2141            // the factory test app, so just sit around displaying the
2142            // error message and don't try to start anything.
2143            return false;
2144        }
2145        Intent intent = new Intent(
2146            mTopAction,
2147            mTopData != null ? Uri.parse(mTopData) : null);
2148        intent.setComponent(mTopComponent);
2149        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2150            intent.addCategory(Intent.CATEGORY_HOME);
2151        }
2152        ActivityInfo aInfo =
2153            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2154        if (aInfo != null) {
2155            intent.setComponent(new ComponentName(
2156                    aInfo.applicationInfo.packageName, aInfo.name));
2157            // Don't do this if the home app is currently being
2158            // instrumented.
2159            aInfo = new ActivityInfo(aInfo);
2160            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2161            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2162                    aInfo.applicationInfo.uid);
2163            if (app == null || app.instrumentationClass == null) {
2164                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2165                mMainStack.startActivityLocked(null, intent, null, aInfo,
2166                        null, null, 0, 0, 0, 0, null, false, null);
2167            }
2168        }
2169        if (startingUser != null) {
2170            mMainStack.addStartingUserLocked(startingUser);
2171        }
2172
2173        return true;
2174    }
2175
2176    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2177        ActivityInfo ai = null;
2178        ComponentName comp = intent.getComponent();
2179        try {
2180            if (comp != null) {
2181                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2182            } else {
2183                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2184                        intent,
2185                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2186                            flags, userId);
2187
2188                if (info != null) {
2189                    ai = info.activityInfo;
2190                }
2191            }
2192        } catch (RemoteException e) {
2193            // ignore
2194        }
2195
2196        return ai;
2197    }
2198
2199    /**
2200     * Starts the "new version setup screen" if appropriate.
2201     */
2202    void startSetupActivityLocked() {
2203        // Only do this once per boot.
2204        if (mCheckedForSetup) {
2205            return;
2206        }
2207
2208        // We will show this screen if the current one is a different
2209        // version than the last one shown, and we are not running in
2210        // low-level factory test mode.
2211        final ContentResolver resolver = mContext.getContentResolver();
2212        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2213                Settings.Secure.getInt(resolver,
2214                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2215            mCheckedForSetup = true;
2216
2217            // See if we should be showing the platform update setup UI.
2218            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2219            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2220                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2221
2222            // We don't allow third party apps to replace this.
2223            ResolveInfo ri = null;
2224            for (int i=0; ris != null && i<ris.size(); i++) {
2225                if ((ris.get(i).activityInfo.applicationInfo.flags
2226                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2227                    ri = ris.get(i);
2228                    break;
2229                }
2230            }
2231
2232            if (ri != null) {
2233                String vers = ri.activityInfo.metaData != null
2234                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2235                        : null;
2236                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2237                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2238                            Intent.METADATA_SETUP_VERSION);
2239                }
2240                String lastVers = Settings.Secure.getString(
2241                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2242                if (vers != null && !vers.equals(lastVers)) {
2243                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2244                    intent.setComponent(new ComponentName(
2245                            ri.activityInfo.packageName, ri.activityInfo.name));
2246                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2247                            null, null, 0, 0, 0, 0, null, false, null);
2248                }
2249            }
2250        }
2251    }
2252
2253    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2254        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2255    }
2256
2257    void enforceNotIsolatedCaller(String caller) {
2258        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2259            throw new SecurityException("Isolated process not allowed to call " + caller);
2260        }
2261    }
2262
2263    public int getFrontActivityScreenCompatMode() {
2264        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2265        synchronized (this) {
2266            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2267        }
2268    }
2269
2270    public void setFrontActivityScreenCompatMode(int mode) {
2271        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2272                "setFrontActivityScreenCompatMode");
2273        synchronized (this) {
2274            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2275        }
2276    }
2277
2278    public int getPackageScreenCompatMode(String packageName) {
2279        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2280        synchronized (this) {
2281            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2282        }
2283    }
2284
2285    public void setPackageScreenCompatMode(String packageName, int mode) {
2286        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2287                "setPackageScreenCompatMode");
2288        synchronized (this) {
2289            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2290        }
2291    }
2292
2293    public boolean getPackageAskScreenCompat(String packageName) {
2294        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2295        synchronized (this) {
2296            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2297        }
2298    }
2299
2300    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2301        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2302                "setPackageAskScreenCompat");
2303        synchronized (this) {
2304            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2305        }
2306    }
2307
2308    void reportResumedActivityLocked(ActivityRecord r) {
2309        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2310        updateUsageStats(r, true);
2311    }
2312
2313    private void dispatchProcessesChanged() {
2314        int N;
2315        synchronized (this) {
2316            N = mPendingProcessChanges.size();
2317            if (mActiveProcessChanges.length < N) {
2318                mActiveProcessChanges = new ProcessChangeItem[N];
2319            }
2320            mPendingProcessChanges.toArray(mActiveProcessChanges);
2321            mAvailProcessChanges.addAll(mPendingProcessChanges);
2322            mPendingProcessChanges.clear();
2323            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2324        }
2325        int i = mProcessObservers.beginBroadcast();
2326        while (i > 0) {
2327            i--;
2328            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2329            if (observer != null) {
2330                try {
2331                    for (int j=0; j<N; j++) {
2332                        ProcessChangeItem item = mActiveProcessChanges[j];
2333                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2334                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2335                                    + item.pid + " uid=" + item.uid + ": "
2336                                    + item.foregroundActivities);
2337                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2338                                    item.foregroundActivities);
2339                        }
2340                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2341                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2342                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2343                            observer.onImportanceChanged(item.pid, item.uid,
2344                                    item.importance);
2345                        }
2346                    }
2347                } catch (RemoteException e) {
2348                }
2349            }
2350        }
2351        mProcessObservers.finishBroadcast();
2352    }
2353
2354    private void dispatchProcessDied(int pid, int uid) {
2355        int i = mProcessObservers.beginBroadcast();
2356        while (i > 0) {
2357            i--;
2358            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2359            if (observer != null) {
2360                try {
2361                    observer.onProcessDied(pid, uid);
2362                } catch (RemoteException e) {
2363                }
2364            }
2365        }
2366        mProcessObservers.finishBroadcast();
2367    }
2368
2369    final void doPendingActivityLaunchesLocked(boolean doResume) {
2370        final int N = mPendingActivityLaunches.size();
2371        if (N <= 0) {
2372            return;
2373        }
2374        for (int i=0; i<N; i++) {
2375            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2376            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2377                    pal.startFlags, doResume && i == (N-1), null);
2378        }
2379        mPendingActivityLaunches.clear();
2380    }
2381
2382    public final int startActivity(IApplicationThread caller,
2383            Intent intent, String resolvedType, IBinder resultTo,
2384            String resultWho, int requestCode, int startFlags,
2385            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2386        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2387                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2388    }
2389
2390    public final int startActivityAsUser(IApplicationThread caller,
2391            Intent intent, String resolvedType, IBinder resultTo,
2392            String resultWho, int requestCode, int startFlags,
2393            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2394        enforceNotIsolatedCaller("startActivity");
2395        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2396                false, true, "startActivity", null);
2397        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2398                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2399                null, null, options, userId);
2400    }
2401
2402    public final WaitResult startActivityAndWait(IApplicationThread caller,
2403            Intent intent, String resolvedType, IBinder resultTo,
2404            String resultWho, int requestCode, int startFlags, String profileFile,
2405            ParcelFileDescriptor profileFd, Bundle options, int userId) {
2406        enforceNotIsolatedCaller("startActivityAndWait");
2407        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2408                false, true, "startActivityAndWait", null);
2409        WaitResult res = new WaitResult();
2410        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2411                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2412                res, null, options, UserHandle.getCallingUserId());
2413        return res;
2414    }
2415
2416    public final int startActivityWithConfig(IApplicationThread caller,
2417            Intent intent, String resolvedType, IBinder resultTo,
2418            String resultWho, int requestCode, int startFlags, Configuration config,
2419            Bundle options, int userId) {
2420        enforceNotIsolatedCaller("startActivityWithConfig");
2421        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2422                false, true, "startActivityWithConfig", null);
2423        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2424                resultTo, resultWho, requestCode, startFlags,
2425                null, null, null, config, options, userId);
2426        return ret;
2427    }
2428
2429    public int startActivityIntentSender(IApplicationThread caller,
2430            IntentSender intent, Intent fillInIntent, String resolvedType,
2431            IBinder resultTo, String resultWho, int requestCode,
2432            int flagsMask, int flagsValues, Bundle options) {
2433        enforceNotIsolatedCaller("startActivityIntentSender");
2434        // Refuse possible leaked file descriptors
2435        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2436            throw new IllegalArgumentException("File descriptors passed in Intent");
2437        }
2438
2439        IIntentSender sender = intent.getTarget();
2440        if (!(sender instanceof PendingIntentRecord)) {
2441            throw new IllegalArgumentException("Bad PendingIntent object");
2442        }
2443
2444        PendingIntentRecord pir = (PendingIntentRecord)sender;
2445
2446        synchronized (this) {
2447            // If this is coming from the currently resumed activity, it is
2448            // effectively saying that app switches are allowed at this point.
2449            if (mMainStack.mResumedActivity != null
2450                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2451                            Binder.getCallingUid()) {
2452                mAppSwitchesAllowedTime = 0;
2453            }
2454        }
2455        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2456                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2457        return ret;
2458    }
2459
2460    public boolean startNextMatchingActivity(IBinder callingActivity,
2461            Intent intent, Bundle options) {
2462        // Refuse possible leaked file descriptors
2463        if (intent != null && intent.hasFileDescriptors() == true) {
2464            throw new IllegalArgumentException("File descriptors passed in Intent");
2465        }
2466
2467        synchronized (this) {
2468            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2469            if (r == null) {
2470                ActivityOptions.abort(options);
2471                return false;
2472            }
2473            if (r.app == null || r.app.thread == null) {
2474                // The caller is not running...  d'oh!
2475                ActivityOptions.abort(options);
2476                return false;
2477            }
2478            intent = new Intent(intent);
2479            // The caller is not allowed to change the data.
2480            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2481            // And we are resetting to find the next component...
2482            intent.setComponent(null);
2483
2484            ActivityInfo aInfo = null;
2485            try {
2486                List<ResolveInfo> resolves =
2487                    AppGlobals.getPackageManager().queryIntentActivities(
2488                            intent, r.resolvedType,
2489                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2490                            UserHandle.getCallingUserId());
2491
2492                // Look for the original activity in the list...
2493                final int N = resolves != null ? resolves.size() : 0;
2494                for (int i=0; i<N; i++) {
2495                    ResolveInfo rInfo = resolves.get(i);
2496                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2497                            && rInfo.activityInfo.name.equals(r.info.name)) {
2498                        // We found the current one...  the next matching is
2499                        // after it.
2500                        i++;
2501                        if (i<N) {
2502                            aInfo = resolves.get(i).activityInfo;
2503                        }
2504                        break;
2505                    }
2506                }
2507            } catch (RemoteException e) {
2508            }
2509
2510            if (aInfo == null) {
2511                // Nobody who is next!
2512                ActivityOptions.abort(options);
2513                return false;
2514            }
2515
2516            intent.setComponent(new ComponentName(
2517                    aInfo.applicationInfo.packageName, aInfo.name));
2518            intent.setFlags(intent.getFlags()&~(
2519                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2520                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2521                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2522                    Intent.FLAG_ACTIVITY_NEW_TASK));
2523
2524            // Okay now we need to start the new activity, replacing the
2525            // currently running activity.  This is a little tricky because
2526            // we want to start the new one as if the current one is finished,
2527            // but not finish the current one first so that there is no flicker.
2528            // And thus...
2529            final boolean wasFinishing = r.finishing;
2530            r.finishing = true;
2531
2532            // Propagate reply information over to the new activity.
2533            final ActivityRecord resultTo = r.resultTo;
2534            final String resultWho = r.resultWho;
2535            final int requestCode = r.requestCode;
2536            r.resultTo = null;
2537            if (resultTo != null) {
2538                resultTo.removeResultsLocked(r, resultWho, requestCode);
2539            }
2540
2541            final long origId = Binder.clearCallingIdentity();
2542            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2543                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2544                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2545                    options, false, null);
2546            Binder.restoreCallingIdentity(origId);
2547
2548            r.finishing = wasFinishing;
2549            if (res != ActivityManager.START_SUCCESS) {
2550                return false;
2551            }
2552            return true;
2553        }
2554    }
2555
2556    final int startActivityInPackage(int uid,
2557            Intent intent, String resolvedType, IBinder resultTo,
2558            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2559
2560        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2561                false, true, "startActivityInPackage", null);
2562
2563        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2564                resultTo, resultWho, requestCode, startFlags,
2565                null, null, null, null, options, userId);
2566        return ret;
2567    }
2568
2569    public final int startActivities(IApplicationThread caller,
2570            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2571        enforceNotIsolatedCaller("startActivities");
2572        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2573                options, UserHandle.getCallingUserId());
2574        return ret;
2575    }
2576
2577    final int startActivitiesInPackage(int uid,
2578            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2579            Bundle options, int userId) {
2580
2581        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2582                false, true, "startActivityInPackage", null);
2583        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2584                options, userId);
2585        return ret;
2586    }
2587
2588    final void addRecentTaskLocked(TaskRecord task) {
2589        int N = mRecentTasks.size();
2590        // Quick case: check if the top-most recent task is the same.
2591        if (N > 0 && mRecentTasks.get(0) == task) {
2592            return;
2593        }
2594        // Remove any existing entries that are the same kind of task.
2595        for (int i=0; i<N; i++) {
2596            TaskRecord tr = mRecentTasks.get(i);
2597            if (task.userId == tr.userId
2598                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2599                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2600                mRecentTasks.remove(i);
2601                i--;
2602                N--;
2603                if (task.intent == null) {
2604                    // If the new recent task we are adding is not fully
2605                    // specified, then replace it with the existing recent task.
2606                    task = tr;
2607                }
2608            }
2609        }
2610        if (N >= MAX_RECENT_TASKS) {
2611            mRecentTasks.remove(N-1);
2612        }
2613        mRecentTasks.add(0, task);
2614    }
2615
2616    public void setRequestedOrientation(IBinder token,
2617            int requestedOrientation) {
2618        synchronized (this) {
2619            ActivityRecord r = mMainStack.isInStackLocked(token);
2620            if (r == null) {
2621                return;
2622            }
2623            final long origId = Binder.clearCallingIdentity();
2624            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2625            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2626                    mConfiguration,
2627                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2628            if (config != null) {
2629                r.frozenBeforeDestroy = true;
2630                if (!updateConfigurationLocked(config, r, false, false)) {
2631                    mMainStack.resumeTopActivityLocked(null);
2632                }
2633            }
2634            Binder.restoreCallingIdentity(origId);
2635        }
2636    }
2637
2638    public int getRequestedOrientation(IBinder token) {
2639        synchronized (this) {
2640            ActivityRecord r = mMainStack.isInStackLocked(token);
2641            if (r == null) {
2642                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2643            }
2644            return mWindowManager.getAppOrientation(r.appToken);
2645        }
2646    }
2647
2648    /**
2649     * This is the internal entry point for handling Activity.finish().
2650     *
2651     * @param token The Binder token referencing the Activity we want to finish.
2652     * @param resultCode Result code, if any, from this Activity.
2653     * @param resultData Result data (Intent), if any, from this Activity.
2654     *
2655     * @return Returns true if the activity successfully finished, or false if it is still running.
2656     */
2657    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2658        // Refuse possible leaked file descriptors
2659        if (resultData != null && resultData.hasFileDescriptors() == true) {
2660            throw new IllegalArgumentException("File descriptors passed in Intent");
2661        }
2662
2663        synchronized(this) {
2664            if (mController != null) {
2665                // Find the first activity that is not finishing.
2666                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2667                if (next != null) {
2668                    // ask watcher if this is allowed
2669                    boolean resumeOK = true;
2670                    try {
2671                        resumeOK = mController.activityResuming(next.packageName);
2672                    } catch (RemoteException e) {
2673                        mController = null;
2674                    }
2675
2676                    if (!resumeOK) {
2677                        return false;
2678                    }
2679                }
2680            }
2681            final long origId = Binder.clearCallingIdentity();
2682            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2683                    resultData, "app-request");
2684            Binder.restoreCallingIdentity(origId);
2685            return res;
2686        }
2687    }
2688
2689    public final void finishHeavyWeightApp() {
2690        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2691                != PackageManager.PERMISSION_GRANTED) {
2692            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2693                    + Binder.getCallingPid()
2694                    + ", uid=" + Binder.getCallingUid()
2695                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2696            Slog.w(TAG, msg);
2697            throw new SecurityException(msg);
2698        }
2699
2700        synchronized(this) {
2701            if (mHeavyWeightProcess == null) {
2702                return;
2703            }
2704
2705            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2706                    mHeavyWeightProcess.activities);
2707            for (int i=0; i<activities.size(); i++) {
2708                ActivityRecord r = activities.get(i);
2709                if (!r.finishing) {
2710                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2711                    if (index >= 0) {
2712                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2713                                null, "finish-heavy");
2714                    }
2715                }
2716            }
2717
2718            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2719                    mHeavyWeightProcess.userId, 0));
2720            mHeavyWeightProcess = null;
2721        }
2722    }
2723
2724    public void crashApplication(int uid, int initialPid, String packageName,
2725            String message) {
2726        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2727                != PackageManager.PERMISSION_GRANTED) {
2728            String msg = "Permission Denial: crashApplication() from pid="
2729                    + Binder.getCallingPid()
2730                    + ", uid=" + Binder.getCallingUid()
2731                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2732            Slog.w(TAG, msg);
2733            throw new SecurityException(msg);
2734        }
2735
2736        synchronized(this) {
2737            ProcessRecord proc = null;
2738
2739            // Figure out which process to kill.  We don't trust that initialPid
2740            // still has any relation to current pids, so must scan through the
2741            // list.
2742            synchronized (mPidsSelfLocked) {
2743                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2744                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2745                    if (p.uid != uid) {
2746                        continue;
2747                    }
2748                    if (p.pid == initialPid) {
2749                        proc = p;
2750                        break;
2751                    }
2752                    for (String str : p.pkgList) {
2753                        if (str.equals(packageName)) {
2754                            proc = p;
2755                        }
2756                    }
2757                }
2758            }
2759
2760            if (proc == null) {
2761                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2762                        + " initialPid=" + initialPid
2763                        + " packageName=" + packageName);
2764                return;
2765            }
2766
2767            if (proc.thread != null) {
2768                if (proc.pid == Process.myPid()) {
2769                    Log.w(TAG, "crashApplication: trying to crash self!");
2770                    return;
2771                }
2772                long ident = Binder.clearCallingIdentity();
2773                try {
2774                    proc.thread.scheduleCrash(message);
2775                } catch (RemoteException e) {
2776                }
2777                Binder.restoreCallingIdentity(ident);
2778            }
2779        }
2780    }
2781
2782    public final void finishSubActivity(IBinder token, String resultWho,
2783            int requestCode) {
2784        synchronized(this) {
2785            final long origId = Binder.clearCallingIdentity();
2786            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2787            Binder.restoreCallingIdentity(origId);
2788        }
2789    }
2790
2791    public boolean finishActivityAffinity(IBinder token) {
2792        synchronized(this) {
2793            final long origId = Binder.clearCallingIdentity();
2794            boolean res = mMainStack.finishActivityAffinityLocked(token);
2795            Binder.restoreCallingIdentity(origId);
2796            return res;
2797        }
2798    }
2799
2800    public boolean willActivityBeVisible(IBinder token) {
2801        synchronized(this) {
2802            int i;
2803            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2804                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2805                if (r.appToken == token) {
2806                    return true;
2807                }
2808                if (r.fullscreen && !r.finishing) {
2809                    return false;
2810                }
2811            }
2812            return true;
2813        }
2814    }
2815
2816    public void overridePendingTransition(IBinder token, String packageName,
2817            int enterAnim, int exitAnim) {
2818        synchronized(this) {
2819            ActivityRecord self = mMainStack.isInStackLocked(token);
2820            if (self == null) {
2821                return;
2822            }
2823
2824            final long origId = Binder.clearCallingIdentity();
2825
2826            if (self.state == ActivityState.RESUMED
2827                    || self.state == ActivityState.PAUSING) {
2828                mWindowManager.overridePendingAppTransition(packageName,
2829                        enterAnim, exitAnim, null);
2830            }
2831
2832            Binder.restoreCallingIdentity(origId);
2833        }
2834    }
2835
2836    /**
2837     * Main function for removing an existing process from the activity manager
2838     * as a result of that process going away.  Clears out all connections
2839     * to the process.
2840     */
2841    private final void handleAppDiedLocked(ProcessRecord app,
2842            boolean restarting, boolean allowRestart) {
2843        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2844        if (!restarting) {
2845            mLruProcesses.remove(app);
2846        }
2847
2848        if (mProfileProc == app) {
2849            clearProfilerLocked();
2850        }
2851
2852        // Just in case...
2853        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2854            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2855            mMainStack.mPausingActivity = null;
2856        }
2857        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2858            mMainStack.mLastPausedActivity = null;
2859        }
2860
2861        // Remove this application's activities from active lists.
2862        mMainStack.removeHistoryRecordsForAppLocked(app);
2863
2864        boolean atTop = true;
2865        boolean hasVisibleActivities = false;
2866
2867        // Clean out the history list.
2868        int i = mMainStack.mHistory.size();
2869        if (localLOGV) Slog.v(
2870            TAG, "Removing app " + app + " from history with " + i + " entries");
2871        while (i > 0) {
2872            i--;
2873            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2874            if (localLOGV) Slog.v(
2875                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2876            if (r.app == app) {
2877                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2878                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2879                        RuntimeException here = new RuntimeException("here");
2880                        here.fillInStackTrace();
2881                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2882                                + ": haveState=" + r.haveState
2883                                + " stateNotNeeded=" + r.stateNotNeeded
2884                                + " finishing=" + r.finishing
2885                                + " state=" + r.state, here);
2886                    }
2887                    if (!r.finishing) {
2888                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2889                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2890                                System.identityHashCode(r),
2891                                r.task.taskId, r.shortComponentName,
2892                                "proc died without state saved");
2893                    }
2894                    mMainStack.removeActivityFromHistoryLocked(r);
2895
2896                } else {
2897                    // We have the current state for this activity, so
2898                    // it can be restarted later when needed.
2899                    if (localLOGV) Slog.v(
2900                        TAG, "Keeping entry, setting app to null");
2901                    if (r.visible) {
2902                        hasVisibleActivities = true;
2903                    }
2904                    r.app = null;
2905                    r.nowVisible = false;
2906                    if (!r.haveState) {
2907                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2908                                "App died, clearing saved state of " + r);
2909                        r.icicle = null;
2910                    }
2911                }
2912
2913                r.stack.cleanUpActivityLocked(r, true, true);
2914            }
2915            atTop = false;
2916        }
2917
2918        app.activities.clear();
2919
2920        if (app.instrumentationClass != null) {
2921            Slog.w(TAG, "Crash of app " + app.processName
2922                  + " running instrumentation " + app.instrumentationClass);
2923            Bundle info = new Bundle();
2924            info.putString("shortMsg", "Process crashed.");
2925            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2926        }
2927
2928        if (!restarting) {
2929            if (!mMainStack.resumeTopActivityLocked(null)) {
2930                // If there was nothing to resume, and we are not already
2931                // restarting this process, but there is a visible activity that
2932                // is hosted by the process...  then make sure all visible
2933                // activities are running, taking care of restarting this
2934                // process.
2935                if (hasVisibleActivities) {
2936                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2937                }
2938            }
2939        }
2940    }
2941
2942    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2943        IBinder threadBinder = thread.asBinder();
2944        // Find the application record.
2945        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2946            ProcessRecord rec = mLruProcesses.get(i);
2947            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2948                return i;
2949            }
2950        }
2951        return -1;
2952    }
2953
2954    final ProcessRecord getRecordForAppLocked(
2955            IApplicationThread thread) {
2956        if (thread == null) {
2957            return null;
2958        }
2959
2960        int appIndex = getLRURecordIndexForAppLocked(thread);
2961        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2962    }
2963
2964    final void appDiedLocked(ProcessRecord app, int pid,
2965            IApplicationThread thread) {
2966
2967        mProcDeaths[0]++;
2968
2969        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2970        synchronized (stats) {
2971            stats.noteProcessDiedLocked(app.info.uid, pid);
2972        }
2973
2974        // Clean up already done if the process has been re-started.
2975        if (app.pid == pid && app.thread != null &&
2976                app.thread.asBinder() == thread.asBinder()) {
2977            if (!app.killedBackground) {
2978                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2979                        + ") has died.");
2980            }
2981            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2982            if (localLOGV) Slog.v(
2983                TAG, "Dying app: " + app + ", pid: " + pid
2984                + ", thread: " + thread.asBinder());
2985            boolean doLowMem = app.instrumentationClass == null;
2986            handleAppDiedLocked(app, false, true);
2987
2988            if (doLowMem) {
2989                // If there are no longer any background processes running,
2990                // and the app that died was not running instrumentation,
2991                // then tell everyone we are now low on memory.
2992                boolean haveBg = false;
2993                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2994                    ProcessRecord rec = mLruProcesses.get(i);
2995                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2996                        haveBg = true;
2997                        break;
2998                    }
2999                }
3000
3001                if (!haveBg) {
3002                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3003                    long now = SystemClock.uptimeMillis();
3004                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
3005                        ProcessRecord rec = mLruProcesses.get(i);
3006                        if (rec != app && rec.thread != null &&
3007                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3008                            // The low memory report is overriding any current
3009                            // state for a GC request.  Make sure to do
3010                            // heavy/important/visible/foreground processes first.
3011                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3012                                rec.lastRequestedGc = 0;
3013                            } else {
3014                                rec.lastRequestedGc = rec.lastLowMemory;
3015                            }
3016                            rec.reportLowMemory = true;
3017                            rec.lastLowMemory = now;
3018                            mProcessesToGc.remove(rec);
3019                            addProcessToGcListLocked(rec);
3020                        }
3021                    }
3022                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3023                    scheduleAppGcsLocked();
3024                }
3025            }
3026        } else if (app.pid != pid) {
3027            // A new process has already been started.
3028            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3029                    + ") has died and restarted (pid " + app.pid + ").");
3030            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3031        } else if (DEBUG_PROCESSES) {
3032            Slog.d(TAG, "Received spurious death notification for thread "
3033                    + thread.asBinder());
3034        }
3035    }
3036
3037    /**
3038     * If a stack trace dump file is configured, dump process stack traces.
3039     * @param clearTraces causes the dump file to be erased prior to the new
3040     *    traces being written, if true; when false, the new traces will be
3041     *    appended to any existing file content.
3042     * @param firstPids of dalvik VM processes to dump stack traces for first
3043     * @param lastPids of dalvik VM processes to dump stack traces for last
3044     * @param nativeProcs optional list of native process names to dump stack crawls
3045     * @return file containing stack traces, or null if no dump file is configured
3046     */
3047    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3048            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3049        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3050        if (tracesPath == null || tracesPath.length() == 0) {
3051            return null;
3052        }
3053
3054        File tracesFile = new File(tracesPath);
3055        try {
3056            File tracesDir = tracesFile.getParentFile();
3057            if (!tracesDir.exists()) {
3058                tracesFile.mkdirs();
3059                if (!SELinux.restorecon(tracesDir)) {
3060                    return null;
3061                }
3062            }
3063            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3064
3065            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3066            tracesFile.createNewFile();
3067            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3068        } catch (IOException e) {
3069            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3070            return null;
3071        }
3072
3073        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3074        return tracesFile;
3075    }
3076
3077    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3078            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3079        // Use a FileObserver to detect when traces finish writing.
3080        // The order of traces is considered important to maintain for legibility.
3081        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3082            public synchronized void onEvent(int event, String path) { notify(); }
3083        };
3084
3085        try {
3086            observer.startWatching();
3087
3088            // First collect all of the stacks of the most important pids.
3089            if (firstPids != null) {
3090                try {
3091                    int num = firstPids.size();
3092                    for (int i = 0; i < num; i++) {
3093                        synchronized (observer) {
3094                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3095                            observer.wait(200);  // Wait for write-close, give up after 200msec
3096                        }
3097                    }
3098                } catch (InterruptedException e) {
3099                    Log.wtf(TAG, e);
3100                }
3101            }
3102
3103            // Next measure CPU usage.
3104            if (processStats != null) {
3105                processStats.init();
3106                System.gc();
3107                processStats.update();
3108                try {
3109                    synchronized (processStats) {
3110                        processStats.wait(500); // measure over 1/2 second.
3111                    }
3112                } catch (InterruptedException e) {
3113                }
3114                processStats.update();
3115
3116                // We'll take the stack crawls of just the top apps using CPU.
3117                final int N = processStats.countWorkingStats();
3118                int numProcs = 0;
3119                for (int i=0; i<N && numProcs<5; i++) {
3120                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3121                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3122                        numProcs++;
3123                        try {
3124                            synchronized (observer) {
3125                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3126                                observer.wait(200);  // Wait for write-close, give up after 200msec
3127                            }
3128                        } catch (InterruptedException e) {
3129                            Log.wtf(TAG, e);
3130                        }
3131
3132                    }
3133                }
3134            }
3135
3136        } finally {
3137            observer.stopWatching();
3138        }
3139
3140        if (nativeProcs != null) {
3141            int[] pids = Process.getPidsForCommands(nativeProcs);
3142            if (pids != null) {
3143                for (int pid : pids) {
3144                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3145                }
3146            }
3147        }
3148    }
3149
3150    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3151        if (true || IS_USER_BUILD) {
3152            return;
3153        }
3154        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3155        if (tracesPath == null || tracesPath.length() == 0) {
3156            return;
3157        }
3158
3159        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3160        StrictMode.allowThreadDiskWrites();
3161        try {
3162            final File tracesFile = new File(tracesPath);
3163            final File tracesDir = tracesFile.getParentFile();
3164            final File tracesTmp = new File(tracesDir, "__tmp__");
3165            try {
3166                if (!tracesDir.exists()) {
3167                    tracesFile.mkdirs();
3168                    if (!SELinux.restorecon(tracesDir.getPath())) {
3169                        return;
3170                    }
3171                }
3172                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3173
3174                if (tracesFile.exists()) {
3175                    tracesTmp.delete();
3176                    tracesFile.renameTo(tracesTmp);
3177                }
3178                StringBuilder sb = new StringBuilder();
3179                Time tobj = new Time();
3180                tobj.set(System.currentTimeMillis());
3181                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3182                sb.append(": ");
3183                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3184                sb.append(" since ");
3185                sb.append(msg);
3186                FileOutputStream fos = new FileOutputStream(tracesFile);
3187                fos.write(sb.toString().getBytes());
3188                if (app == null) {
3189                    fos.write("\n*** No application process!".getBytes());
3190                }
3191                fos.close();
3192                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3193            } catch (IOException e) {
3194                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3195                return;
3196            }
3197
3198            if (app != null) {
3199                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3200                firstPids.add(app.pid);
3201                dumpStackTraces(tracesPath, firstPids, null, null, null);
3202            }
3203
3204            File lastTracesFile = null;
3205            File curTracesFile = null;
3206            for (int i=9; i>=0; i--) {
3207                String name = String.format("slow%02d.txt", i);
3208                curTracesFile = new File(tracesDir, name);
3209                if (curTracesFile.exists()) {
3210                    if (lastTracesFile != null) {
3211                        curTracesFile.renameTo(lastTracesFile);
3212                    } else {
3213                        curTracesFile.delete();
3214                    }
3215                }
3216                lastTracesFile = curTracesFile;
3217            }
3218            tracesFile.renameTo(curTracesFile);
3219            if (tracesTmp.exists()) {
3220                tracesTmp.renameTo(tracesFile);
3221            }
3222        } finally {
3223            StrictMode.setThreadPolicy(oldPolicy);
3224        }
3225    }
3226
3227    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3228            ActivityRecord parent, final String annotation) {
3229        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3230        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3231
3232        if (mController != null) {
3233            try {
3234                // 0 == continue, -1 = kill process immediately
3235                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3236                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3237            } catch (RemoteException e) {
3238                mController = null;
3239            }
3240        }
3241
3242        long anrTime = SystemClock.uptimeMillis();
3243        if (MONITOR_CPU_USAGE) {
3244            updateCpuStatsNow();
3245        }
3246
3247        synchronized (this) {
3248            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3249            if (mShuttingDown) {
3250                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3251                return;
3252            } else if (app.notResponding) {
3253                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3254                return;
3255            } else if (app.crashing) {
3256                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3257                return;
3258            }
3259
3260            // In case we come through here for the same app before completing
3261            // this one, mark as anring now so we will bail out.
3262            app.notResponding = true;
3263
3264            // Log the ANR to the event log.
3265            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3266                    annotation);
3267
3268            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3269            firstPids.add(app.pid);
3270
3271            int parentPid = app.pid;
3272            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3273            if (parentPid != app.pid) firstPids.add(parentPid);
3274
3275            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3276
3277            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3278                ProcessRecord r = mLruProcesses.get(i);
3279                if (r != null && r.thread != null) {
3280                    int pid = r.pid;
3281                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3282                        if (r.persistent) {
3283                            firstPids.add(pid);
3284                        } else {
3285                            lastPids.put(pid, Boolean.TRUE);
3286                        }
3287                    }
3288                }
3289            }
3290        }
3291
3292        // Log the ANR to the main log.
3293        StringBuilder info = new StringBuilder();
3294        info.setLength(0);
3295        info.append("ANR in ").append(app.processName);
3296        if (activity != null && activity.shortComponentName != null) {
3297            info.append(" (").append(activity.shortComponentName).append(")");
3298        }
3299        info.append("\n");
3300        if (annotation != null) {
3301            info.append("Reason: ").append(annotation).append("\n");
3302        }
3303        if (parent != null && parent != activity) {
3304            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3305        }
3306
3307        final ProcessStats processStats = new ProcessStats(true);
3308
3309        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3310
3311        String cpuInfo = null;
3312        if (MONITOR_CPU_USAGE) {
3313            updateCpuStatsNow();
3314            synchronized (mProcessStatsThread) {
3315                cpuInfo = mProcessStats.printCurrentState(anrTime);
3316            }
3317            info.append(processStats.printCurrentLoad());
3318            info.append(cpuInfo);
3319        }
3320
3321        info.append(processStats.printCurrentState(anrTime));
3322
3323        Slog.e(TAG, info.toString());
3324        if (tracesFile == null) {
3325            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3326            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3327        }
3328
3329        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3330                cpuInfo, tracesFile, null);
3331
3332        if (mController != null) {
3333            try {
3334                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3335                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3336                if (res != 0) {
3337                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3338                    return;
3339                }
3340            } catch (RemoteException e) {
3341                mController = null;
3342            }
3343        }
3344
3345        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3346        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3347                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3348
3349        synchronized (this) {
3350            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3351                Slog.w(TAG, "Killing " + app + ": background ANR");
3352                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3353                        app.processName, app.setAdj, "background ANR");
3354                Process.killProcessQuiet(app.pid);
3355                return;
3356            }
3357
3358            // Set the app's notResponding state, and look up the errorReportReceiver
3359            makeAppNotRespondingLocked(app,
3360                    activity != null ? activity.shortComponentName : null,
3361                    annotation != null ? "ANR " + annotation : "ANR",
3362                    info.toString());
3363
3364            // Bring up the infamous App Not Responding dialog
3365            Message msg = Message.obtain();
3366            HashMap map = new HashMap();
3367            msg.what = SHOW_NOT_RESPONDING_MSG;
3368            msg.obj = map;
3369            map.put("app", app);
3370            if (activity != null) {
3371                map.put("activity", activity);
3372            }
3373
3374            mHandler.sendMessage(msg);
3375        }
3376    }
3377
3378    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3379        if (!mLaunchWarningShown) {
3380            mLaunchWarningShown = true;
3381            mHandler.post(new Runnable() {
3382                @Override
3383                public void run() {
3384                    synchronized (ActivityManagerService.this) {
3385                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3386                        d.show();
3387                        mHandler.postDelayed(new Runnable() {
3388                            @Override
3389                            public void run() {
3390                                synchronized (ActivityManagerService.this) {
3391                                    d.dismiss();
3392                                    mLaunchWarningShown = false;
3393                                }
3394                            }
3395                        }, 4000);
3396                    }
3397                }
3398            });
3399        }
3400    }
3401
3402    public boolean clearApplicationUserData(final String packageName,
3403            final IPackageDataObserver observer, final int userId) {
3404        enforceNotIsolatedCaller("clearApplicationUserData");
3405        int uid = Binder.getCallingUid();
3406        int pid = Binder.getCallingPid();
3407        long callingId = Binder.clearCallingIdentity();
3408        try {
3409            IPackageManager pm = AppGlobals.getPackageManager();
3410            int pkgUid = -1;
3411            synchronized(this) {
3412                try {
3413                    pkgUid = pm.getPackageUid(packageName, userId);
3414                } catch (RemoteException e) {
3415                }
3416                if (pkgUid == -1) {
3417                    Slog.w(TAG, "Invalid packageName:" + packageName);
3418                    return false;
3419                }
3420                if (uid == pkgUid || checkComponentPermission(
3421                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3422                        pid, uid, -1, true)
3423                        == PackageManager.PERMISSION_GRANTED) {
3424                    forceStopPackageLocked(packageName, pkgUid);
3425                } else {
3426                    throw new SecurityException(pid+" does not have permission:"+
3427                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3428                                    "for process:"+packageName);
3429                }
3430            }
3431
3432            try {
3433                //clear application user data
3434                pm.clearApplicationUserData(packageName, observer, userId);
3435                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3436                        Uri.fromParts("package", packageName, null));
3437                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3438                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3439                        null, null, 0, null, null, null, false, false, userId);
3440            } catch (RemoteException e) {
3441            }
3442        } finally {
3443            Binder.restoreCallingIdentity(callingId);
3444        }
3445        return true;
3446    }
3447
3448    public void killBackgroundProcesses(final String packageName) {
3449        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3450                != PackageManager.PERMISSION_GRANTED &&
3451                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3452                        != PackageManager.PERMISSION_GRANTED) {
3453            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3454                    + Binder.getCallingPid()
3455                    + ", uid=" + Binder.getCallingUid()
3456                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3457            Slog.w(TAG, msg);
3458            throw new SecurityException(msg);
3459        }
3460
3461        int userId = UserHandle.getCallingUserId();
3462        long callingId = Binder.clearCallingIdentity();
3463        try {
3464            IPackageManager pm = AppGlobals.getPackageManager();
3465            int pkgUid = -1;
3466            synchronized(this) {
3467                try {
3468                    pkgUid = pm.getPackageUid(packageName, userId);
3469                } catch (RemoteException e) {
3470                }
3471                if (pkgUid == -1) {
3472                    Slog.w(TAG, "Invalid packageName: " + packageName);
3473                    return;
3474                }
3475                killPackageProcessesLocked(packageName, pkgUid, -1,
3476                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3477            }
3478        } finally {
3479            Binder.restoreCallingIdentity(callingId);
3480        }
3481    }
3482
3483    public void killAllBackgroundProcesses() {
3484        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3485                != PackageManager.PERMISSION_GRANTED) {
3486            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3487                    + Binder.getCallingPid()
3488                    + ", uid=" + Binder.getCallingUid()
3489                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3490            Slog.w(TAG, msg);
3491            throw new SecurityException(msg);
3492        }
3493
3494        long callingId = Binder.clearCallingIdentity();
3495        try {
3496            synchronized(this) {
3497                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3498                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3499                    final int NA = apps.size();
3500                    for (int ia=0; ia<NA; ia++) {
3501                        ProcessRecord app = apps.valueAt(ia);
3502                        if (app.persistent) {
3503                            // we don't kill persistent processes
3504                            continue;
3505                        }
3506                        if (app.removed) {
3507                            procs.add(app);
3508                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3509                            app.removed = true;
3510                            procs.add(app);
3511                        }
3512                    }
3513                }
3514
3515                int N = procs.size();
3516                for (int i=0; i<N; i++) {
3517                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3518                }
3519            }
3520        } finally {
3521            Binder.restoreCallingIdentity(callingId);
3522        }
3523    }
3524
3525    public void forceStopPackage(final String packageName) {
3526        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3527                != PackageManager.PERMISSION_GRANTED) {
3528            String msg = "Permission Denial: forceStopPackage() from pid="
3529                    + Binder.getCallingPid()
3530                    + ", uid=" + Binder.getCallingUid()
3531                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3532            Slog.w(TAG, msg);
3533            throw new SecurityException(msg);
3534        }
3535        final int userId = UserHandle.getCallingUserId();
3536        long callingId = Binder.clearCallingIdentity();
3537        try {
3538            IPackageManager pm = AppGlobals.getPackageManager();
3539            int pkgUid = -1;
3540            synchronized(this) {
3541                try {
3542                    pkgUid = pm.getPackageUid(packageName, userId);
3543                } catch (RemoteException e) {
3544                }
3545                if (pkgUid == -1) {
3546                    Slog.w(TAG, "Invalid packageName: " + packageName);
3547                    return;
3548                }
3549                forceStopPackageLocked(packageName, pkgUid);
3550                try {
3551                    pm.setPackageStoppedState(packageName, true, userId);
3552                } catch (RemoteException e) {
3553                } catch (IllegalArgumentException e) {
3554                    Slog.w(TAG, "Failed trying to unstop package "
3555                            + packageName + ": " + e);
3556                }
3557            }
3558        } finally {
3559            Binder.restoreCallingIdentity(callingId);
3560        }
3561    }
3562
3563    /*
3564     * The pkg name and app id have to be specified.
3565     */
3566    public void killApplicationWithAppId(String pkg, int appid) {
3567        if (pkg == null) {
3568            return;
3569        }
3570        // Make sure the uid is valid.
3571        if (appid < 0) {
3572            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
3573            return;
3574        }
3575        int callerUid = Binder.getCallingUid();
3576        // Only the system server can kill an application
3577        if (callerUid == Process.SYSTEM_UID) {
3578            // Post an aysnc message to kill the application
3579            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3580            msg.arg1 = appid;
3581            msg.arg2 = 0;
3582            msg.obj = pkg;
3583            mHandler.sendMessage(msg);
3584        } else {
3585            throw new SecurityException(callerUid + " cannot kill pkg: " +
3586                    pkg);
3587        }
3588    }
3589
3590    public void closeSystemDialogs(String reason) {
3591        enforceNotIsolatedCaller("closeSystemDialogs");
3592
3593        final int pid = Binder.getCallingPid();
3594        final int uid = Binder.getCallingUid();
3595        final long origId = Binder.clearCallingIdentity();
3596        try {
3597            synchronized (this) {
3598                // Only allow this from foreground processes, so that background
3599                // applications can't abuse it to prevent system UI from being shown.
3600                if (uid >= Process.FIRST_APPLICATION_UID) {
3601                    ProcessRecord proc;
3602                    synchronized (mPidsSelfLocked) {
3603                        proc = mPidsSelfLocked.get(pid);
3604                    }
3605                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
3606                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
3607                                + " from background process " + proc);
3608                        return;
3609                    }
3610                }
3611                closeSystemDialogsLocked(reason);
3612            }
3613        } finally {
3614            Binder.restoreCallingIdentity(origId);
3615        }
3616    }
3617
3618    void closeSystemDialogsLocked(String reason) {
3619        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3620        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3621        if (reason != null) {
3622            intent.putExtra("reason", reason);
3623        }
3624        mWindowManager.closeSystemDialogs(reason);
3625
3626        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3627            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3628            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3629                r.stack.finishActivityLocked(r, i,
3630                        Activity.RESULT_CANCELED, null, "close-sys");
3631            }
3632        }
3633
3634        broadcastIntentLocked(null, null, intent, null,
3635                null, 0, null, null, null, false, false, -1,
3636                Process.SYSTEM_UID, UserHandle.USER_ALL);
3637    }
3638
3639    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3640            throws RemoteException {
3641        enforceNotIsolatedCaller("getProcessMemoryInfo");
3642        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3643        for (int i=pids.length-1; i>=0; i--) {
3644            infos[i] = new Debug.MemoryInfo();
3645            Debug.getMemoryInfo(pids[i], infos[i]);
3646        }
3647        return infos;
3648    }
3649
3650    public long[] getProcessPss(int[] pids) throws RemoteException {
3651        enforceNotIsolatedCaller("getProcessPss");
3652        long[] pss = new long[pids.length];
3653        for (int i=pids.length-1; i>=0; i--) {
3654            pss[i] = Debug.getPss(pids[i]);
3655        }
3656        return pss;
3657    }
3658
3659    public void killApplicationProcess(String processName, int uid) {
3660        if (processName == null) {
3661            return;
3662        }
3663
3664        int callerUid = Binder.getCallingUid();
3665        // Only the system server can kill an application
3666        if (callerUid == Process.SYSTEM_UID) {
3667            synchronized (this) {
3668                ProcessRecord app = getProcessRecordLocked(processName, uid);
3669                if (app != null && app.thread != null) {
3670                    try {
3671                        app.thread.scheduleSuicide();
3672                    } catch (RemoteException e) {
3673                        // If the other end already died, then our work here is done.
3674                    }
3675                } else {
3676                    Slog.w(TAG, "Process/uid not found attempting kill of "
3677                            + processName + " / " + uid);
3678                }
3679            }
3680        } else {
3681            throw new SecurityException(callerUid + " cannot kill app process: " +
3682                    processName);
3683        }
3684    }
3685
3686    private void forceStopPackageLocked(final String packageName, int uid) {
3687        forceStopPackageLocked(packageName, uid, false, false, true, false,
3688                UserHandle.getUserId(uid));
3689        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3690                Uri.fromParts("package", packageName, null));
3691        if (!mProcessesReady) {
3692            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3693        }
3694        intent.putExtra(Intent.EXTRA_UID, uid);
3695        broadcastIntentLocked(null, null, intent,
3696                null, null, 0, null, null, null,
3697                false, false,
3698                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3699    }
3700
3701    private void forceStopUserLocked(int userId) {
3702        forceStopPackageLocked(null, -1, false, false, true, false, userId);
3703        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3704        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3705        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3706        broadcastIntentLocked(null, null, intent,
3707                null, null, 0, null, null, null,
3708                false, false,
3709                MY_PID, Process.SYSTEM_UID, userId);
3710    }
3711
3712    private final boolean killPackageProcessesLocked(String packageName, int appId,
3713            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3714            boolean doit, boolean evenPersistent, String reason) {
3715        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3716
3717        // Remove all processes this package may have touched: all with the
3718        // same UID (except for the system or root user), and all whose name
3719        // matches the package name.
3720        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3721        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3722            final int NA = apps.size();
3723            for (int ia=0; ia<NA; ia++) {
3724                ProcessRecord app = apps.valueAt(ia);
3725                if (app.persistent && !evenPersistent) {
3726                    // we don't kill persistent processes
3727                    continue;
3728                }
3729                if (app.removed) {
3730                    if (doit) {
3731                        procs.add(app);
3732                    }
3733                    continue;
3734                }
3735
3736                // Skip process if it doesn't meet our oom adj requirement.
3737                if (app.setAdj < minOomAdj) {
3738                    continue;
3739                }
3740
3741                // If no package is specified, we call all processes under the
3742                // give user id.
3743                if (packageName == null) {
3744                    if (app.userId != userId) {
3745                        continue;
3746                    }
3747                // Package has been specified, we want to hit all processes
3748                // that match it.  We need to qualify this by the processes
3749                // that are running under the specified app and user ID.
3750                } else {
3751                    if (UserHandle.getAppId(app.uid) != appId) {
3752                        continue;
3753                    }
3754                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
3755                        continue;
3756                    }
3757                    if (!app.pkgList.contains(packageName)) {
3758                        continue;
3759                    }
3760                }
3761
3762                // Process has passed all conditions, kill it!
3763                if (!doit) {
3764                    return true;
3765                }
3766                app.removed = true;
3767                procs.add(app);
3768            }
3769        }
3770
3771        int N = procs.size();
3772        for (int i=0; i<N; i++) {
3773            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3774        }
3775        return N > 0;
3776    }
3777
3778    private final boolean forceStopPackageLocked(String name, int appId,
3779            boolean callerWillRestart, boolean purgeCache, boolean doit,
3780            boolean evenPersistent, int userId) {
3781        int i;
3782        int N;
3783
3784        if (userId == UserHandle.USER_ALL && name == null) {
3785            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
3786        }
3787
3788        if (appId < 0 && name != null) {
3789            try {
3790                appId = UserHandle.getAppId(
3791                        AppGlobals.getPackageManager().getPackageUid(name, 0));
3792            } catch (RemoteException e) {
3793            }
3794        }
3795
3796        if (doit) {
3797            if (name != null) {
3798                Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
3799                        + " user=" + userId);
3800            } else {
3801                Slog.i(TAG, "Force stopping user " + userId);
3802            }
3803
3804            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3805            while (badApps.hasNext()) {
3806                SparseArray<Long> ba = badApps.next();
3807                for (i=ba.size()-1; i>=0; i--) {
3808                    boolean remove = false;
3809                    final int entUid = ba.keyAt(i);
3810                    if (name != null) {
3811                        if (userId == UserHandle.USER_ALL) {
3812                            if (UserHandle.getAppId(entUid) == appId) {
3813                                remove = true;
3814                            }
3815                        } else {
3816                            if (entUid == UserHandle.getUid(userId, appId)) {
3817                                remove = true;
3818                            }
3819                        }
3820                    } else if (UserHandle.getUserId(entUid) == userId) {
3821                        remove = true;
3822                    }
3823                    if (remove) {
3824                        ba.removeAt(i);
3825                    }
3826                }
3827                if (ba.size() == 0) {
3828                    badApps.remove();
3829                }
3830            }
3831        }
3832
3833        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
3834                -100, callerWillRestart, false, doit, evenPersistent,
3835                name == null ? ("force stop user " + userId) : ("force stop " + name));
3836
3837        TaskRecord lastTask = null;
3838        for (i=0; i<mMainStack.mHistory.size(); i++) {
3839            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3840            final boolean samePackage = r.packageName.equals(name)
3841                    || (name == null && r.userId == userId);
3842            if ((userId == UserHandle.USER_ALL || r.userId == userId)
3843                    && (samePackage || r.task == lastTask)
3844                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3845                if (!doit) {
3846                    if (r.finishing) {
3847                        // If this activity is just finishing, then it is not
3848                        // interesting as far as something to stop.
3849                        continue;
3850                    }
3851                    return true;
3852                }
3853                didSomething = true;
3854                Slog.i(TAG, "  Force finishing activity " + r);
3855                if (samePackage) {
3856                    if (r.app != null) {
3857                        r.app.removed = true;
3858                    }
3859                    r.app = null;
3860                }
3861                lastTask = r.task;
3862                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3863                        null, "force-stop", true)) {
3864                    i--;
3865                }
3866            }
3867        }
3868
3869        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3870            if (!doit) {
3871                return true;
3872            }
3873            didSomething = true;
3874        }
3875
3876        if (name == null) {
3877            // Remove all sticky broadcasts from this user.
3878            mStickyBroadcasts.remove(userId);
3879        }
3880
3881        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3882        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
3883                userId, providers)) {
3884            if (!doit) {
3885                return true;
3886            }
3887            didSomething = true;
3888        }
3889        N = providers.size();
3890        for (i=0; i<N; i++) {
3891            removeDyingProviderLocked(null, providers.get(i), true);
3892        }
3893
3894        if (mIntentSenderRecords.size() > 0) {
3895            Iterator<WeakReference<PendingIntentRecord>> it
3896                    = mIntentSenderRecords.values().iterator();
3897            while (it.hasNext()) {
3898                WeakReference<PendingIntentRecord> wpir = it.next();
3899                if (wpir == null) {
3900                    it.remove();
3901                    continue;
3902                }
3903                PendingIntentRecord pir = wpir.get();
3904                if (pir == null) {
3905                    it.remove();
3906                    continue;
3907                }
3908                if (name == null) {
3909                    // Stopping user, remove all objects for the user.
3910                    if (pir.key.userId != userId) {
3911                        // Not the same user, skip it.
3912                        continue;
3913                    }
3914                } else {
3915                    if (UserHandle.getAppId(pir.uid) != appId) {
3916                        // Different app id, skip it.
3917                        continue;
3918                    }
3919                    if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
3920                        // Different user, skip it.
3921                        continue;
3922                    }
3923                    if (!pir.key.packageName.equals(name)) {
3924                        // Different package, skip it.
3925                        continue;
3926                    }
3927                }
3928                if (!doit) {
3929                    return true;
3930                }
3931                didSomething = true;
3932                it.remove();
3933                pir.canceled = true;
3934                if (pir.key.activity != null) {
3935                    pir.key.activity.pendingResults.remove(pir.ref);
3936                }
3937            }
3938        }
3939
3940        if (doit) {
3941            if (purgeCache && name != null) {
3942                AttributeCache ac = AttributeCache.instance();
3943                if (ac != null) {
3944                    ac.removePackage(name);
3945                }
3946            }
3947            if (mBooted) {
3948                mMainStack.resumeTopActivityLocked(null);
3949                mMainStack.scheduleIdleLocked();
3950            }
3951        }
3952
3953        return didSomething;
3954    }
3955
3956    private final boolean removeProcessLocked(ProcessRecord app,
3957            boolean callerWillRestart, boolean allowRestart, String reason) {
3958        final String name = app.processName;
3959        final int uid = app.uid;
3960        if (DEBUG_PROCESSES) Slog.d(
3961            TAG, "Force removing proc " + app.toShortString() + " (" + name
3962            + "/" + uid + ")");
3963
3964        mProcessNames.remove(name, uid);
3965        mIsolatedProcesses.remove(app.uid);
3966        if (mHeavyWeightProcess == app) {
3967            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3968                    mHeavyWeightProcess.userId, 0));
3969            mHeavyWeightProcess = null;
3970        }
3971        boolean needRestart = false;
3972        if (app.pid > 0 && app.pid != MY_PID) {
3973            int pid = app.pid;
3974            synchronized (mPidsSelfLocked) {
3975                mPidsSelfLocked.remove(pid);
3976                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3977            }
3978            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3979            handleAppDiedLocked(app, true, allowRestart);
3980            mLruProcesses.remove(app);
3981            Process.killProcessQuiet(pid);
3982
3983            if (app.persistent && !app.isolated) {
3984                if (!callerWillRestart) {
3985                    addAppLocked(app.info, false);
3986                } else {
3987                    needRestart = true;
3988                }
3989            }
3990        } else {
3991            mRemovedProcesses.add(app);
3992        }
3993
3994        return needRestart;
3995    }
3996
3997    private final void processStartTimedOutLocked(ProcessRecord app) {
3998        final int pid = app.pid;
3999        boolean gone = false;
4000        synchronized (mPidsSelfLocked) {
4001            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4002            if (knownApp != null && knownApp.thread == null) {
4003                mPidsSelfLocked.remove(pid);
4004                gone = true;
4005            }
4006        }
4007
4008        if (gone) {
4009            Slog.w(TAG, "Process " + app + " failed to attach");
4010            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
4011                    app.processName);
4012            mProcessNames.remove(app.processName, app.uid);
4013            mIsolatedProcesses.remove(app.uid);
4014            if (mHeavyWeightProcess == app) {
4015                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4016                        mHeavyWeightProcess.userId, 0));
4017                mHeavyWeightProcess = null;
4018            }
4019            // Take care of any launching providers waiting for this process.
4020            checkAppInLaunchingProvidersLocked(app, true);
4021            // Take care of any services that are waiting for the process.
4022            mServices.processStartTimedOutLocked(app);
4023            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
4024                    app.processName, app.setAdj, "start timeout");
4025            Process.killProcessQuiet(pid);
4026            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4027                Slog.w(TAG, "Unattached app died before backup, skipping");
4028                try {
4029                    IBackupManager bm = IBackupManager.Stub.asInterface(
4030                            ServiceManager.getService(Context.BACKUP_SERVICE));
4031                    bm.agentDisconnected(app.info.packageName);
4032                } catch (RemoteException e) {
4033                    // Can't happen; the backup manager is local
4034                }
4035            }
4036            if (isPendingBroadcastProcessLocked(pid)) {
4037                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4038                skipPendingBroadcastLocked(pid);
4039            }
4040        } else {
4041            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4042        }
4043    }
4044
4045    private final boolean attachApplicationLocked(IApplicationThread thread,
4046            int pid) {
4047
4048        // Find the application record that is being attached...  either via
4049        // the pid if we are running in multiple processes, or just pull the
4050        // next app record if we are emulating process with anonymous threads.
4051        ProcessRecord app;
4052        if (pid != MY_PID && pid >= 0) {
4053            synchronized (mPidsSelfLocked) {
4054                app = mPidsSelfLocked.get(pid);
4055            }
4056        } else {
4057            app = null;
4058        }
4059
4060        if (app == null) {
4061            Slog.w(TAG, "No pending application record for pid " + pid
4062                    + " (IApplicationThread " + thread + "); dropping process");
4063            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4064            if (pid > 0 && pid != MY_PID) {
4065                Process.killProcessQuiet(pid);
4066            } else {
4067                try {
4068                    thread.scheduleExit();
4069                } catch (Exception e) {
4070                    // Ignore exceptions.
4071                }
4072            }
4073            return false;
4074        }
4075
4076        // If this application record is still attached to a previous
4077        // process, clean it up now.
4078        if (app.thread != null) {
4079            handleAppDiedLocked(app, true, true);
4080        }
4081
4082        // Tell the process all about itself.
4083
4084        if (localLOGV) Slog.v(
4085                TAG, "Binding process pid " + pid + " to record " + app);
4086
4087        String processName = app.processName;
4088        try {
4089            AppDeathRecipient adr = new AppDeathRecipient(
4090                    app, pid, thread);
4091            thread.asBinder().linkToDeath(adr, 0);
4092            app.deathRecipient = adr;
4093        } catch (RemoteException e) {
4094            app.resetPackageList();
4095            startProcessLocked(app, "link fail", processName);
4096            return false;
4097        }
4098
4099        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
4100
4101        app.thread = thread;
4102        app.curAdj = app.setAdj = -100;
4103        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4104        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4105        app.forcingToForeground = null;
4106        app.foregroundServices = false;
4107        app.hasShownUi = false;
4108        app.debugging = false;
4109
4110        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4111
4112        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4113        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4114
4115        if (!normalMode) {
4116            Slog.i(TAG, "Launching preboot mode app: " + app);
4117        }
4118
4119        if (localLOGV) Slog.v(
4120            TAG, "New app record " + app
4121            + " thread=" + thread.asBinder() + " pid=" + pid);
4122        try {
4123            int testMode = IApplicationThread.DEBUG_OFF;
4124            if (mDebugApp != null && mDebugApp.equals(processName)) {
4125                testMode = mWaitForDebugger
4126                    ? IApplicationThread.DEBUG_WAIT
4127                    : IApplicationThread.DEBUG_ON;
4128                app.debugging = true;
4129                if (mDebugTransient) {
4130                    mDebugApp = mOrigDebugApp;
4131                    mWaitForDebugger = mOrigWaitForDebugger;
4132                }
4133            }
4134            String profileFile = app.instrumentationProfileFile;
4135            ParcelFileDescriptor profileFd = null;
4136            boolean profileAutoStop = false;
4137            if (mProfileApp != null && mProfileApp.equals(processName)) {
4138                mProfileProc = app;
4139                profileFile = mProfileFile;
4140                profileFd = mProfileFd;
4141                profileAutoStop = mAutoStopProfiler;
4142            }
4143            boolean enableOpenGlTrace = false;
4144            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4145                enableOpenGlTrace = true;
4146                mOpenGlTraceApp = null;
4147            }
4148
4149            // If the app is being launched for restore or full backup, set it up specially
4150            boolean isRestrictedBackupMode = false;
4151            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4152                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4153                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4154                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4155            }
4156
4157            ensurePackageDexOpt(app.instrumentationInfo != null
4158                    ? app.instrumentationInfo.packageName
4159                    : app.info.packageName);
4160            if (app.instrumentationClass != null) {
4161                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4162            }
4163            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4164                    + processName + " with config " + mConfiguration);
4165            ApplicationInfo appInfo = app.instrumentationInfo != null
4166                    ? app.instrumentationInfo : app.info;
4167            app.compat = compatibilityInfoForPackageLocked(appInfo);
4168            if (profileFd != null) {
4169                profileFd = profileFd.dup();
4170            }
4171            thread.bindApplication(processName, appInfo, providers,
4172                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4173                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4174                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4175                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4176                    mCoreSettingsObserver.getCoreSettingsLocked());
4177            updateLruProcessLocked(app, false, true);
4178            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4179        } catch (Exception e) {
4180            // todo: Yikes!  What should we do?  For now we will try to
4181            // start another process, but that could easily get us in
4182            // an infinite loop of restarting processes...
4183            Slog.w(TAG, "Exception thrown during bind!", e);
4184
4185            app.resetPackageList();
4186            app.unlinkDeathRecipient();
4187            startProcessLocked(app, "bind fail", processName);
4188            return false;
4189        }
4190
4191        // Remove this record from the list of starting applications.
4192        mPersistentStartingProcesses.remove(app);
4193        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4194                "Attach application locked removing on hold: " + app);
4195        mProcessesOnHold.remove(app);
4196
4197        boolean badApp = false;
4198        boolean didSomething = false;
4199
4200        // See if the top visible activity is waiting to run in this process...
4201        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4202        if (hr != null && normalMode) {
4203            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4204                    && processName.equals(hr.processName)) {
4205                try {
4206                    if (mHeadless) {
4207                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4208                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4209                        didSomething = true;
4210                    }
4211                } catch (Exception e) {
4212                    Slog.w(TAG, "Exception in new application when starting activity "
4213                          + hr.intent.getComponent().flattenToShortString(), e);
4214                    badApp = true;
4215                }
4216            } else {
4217                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4218            }
4219        }
4220
4221        // Find any services that should be running in this process...
4222        if (!badApp) {
4223            try {
4224                didSomething |= mServices.attachApplicationLocked(app, processName);
4225            } catch (Exception e) {
4226                badApp = true;
4227            }
4228        }
4229
4230        // Check if a next-broadcast receiver is in this process...
4231        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4232            try {
4233                didSomething = sendPendingBroadcastsLocked(app);
4234            } catch (Exception e) {
4235                // If the app died trying to launch the receiver we declare it 'bad'
4236                badApp = true;
4237            }
4238        }
4239
4240        // Check whether the next backup agent is in this process...
4241        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4242            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4243            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4244            try {
4245                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4246                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4247                        mBackupTarget.backupMode);
4248            } catch (Exception e) {
4249                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4250                e.printStackTrace();
4251            }
4252        }
4253
4254        if (badApp) {
4255            // todo: Also need to kill application to deal with all
4256            // kinds of exceptions.
4257            handleAppDiedLocked(app, false, true);
4258            return false;
4259        }
4260
4261        if (!didSomething) {
4262            updateOomAdjLocked();
4263        }
4264
4265        return true;
4266    }
4267
4268    public final void attachApplication(IApplicationThread thread) {
4269        synchronized (this) {
4270            int callingPid = Binder.getCallingPid();
4271            final long origId = Binder.clearCallingIdentity();
4272            attachApplicationLocked(thread, callingPid);
4273            Binder.restoreCallingIdentity(origId);
4274        }
4275    }
4276
4277    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4278        final long origId = Binder.clearCallingIdentity();
4279        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4280        if (stopProfiling) {
4281            synchronized (this) {
4282                if (mProfileProc == r.app) {
4283                    if (mProfileFd != null) {
4284                        try {
4285                            mProfileFd.close();
4286                        } catch (IOException e) {
4287                        }
4288                        clearProfilerLocked();
4289                    }
4290                }
4291            }
4292        }
4293        Binder.restoreCallingIdentity(origId);
4294    }
4295
4296    void enableScreenAfterBoot() {
4297        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4298                SystemClock.uptimeMillis());
4299        mWindowManager.enableScreenAfterBoot();
4300
4301        synchronized (this) {
4302            updateEventDispatchingLocked();
4303        }
4304    }
4305
4306    public void showBootMessage(final CharSequence msg, final boolean always) {
4307        enforceNotIsolatedCaller("showBootMessage");
4308        mWindowManager.showBootMessage(msg, always);
4309    }
4310
4311    public void dismissKeyguardOnNextActivity() {
4312        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4313        final long token = Binder.clearCallingIdentity();
4314        try {
4315            synchronized (this) {
4316                if (mLockScreenShown) {
4317                    mLockScreenShown = false;
4318                    comeOutOfSleepIfNeededLocked();
4319                }
4320                mMainStack.dismissKeyguardOnNextActivityLocked();
4321            }
4322        } finally {
4323            Binder.restoreCallingIdentity(token);
4324        }
4325    }
4326
4327    final void finishBooting() {
4328        IntentFilter pkgFilter = new IntentFilter();
4329        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4330        pkgFilter.addDataScheme("package");
4331        mContext.registerReceiver(new BroadcastReceiver() {
4332            @Override
4333            public void onReceive(Context context, Intent intent) {
4334                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4335                if (pkgs != null) {
4336                    for (String pkg : pkgs) {
4337                        synchronized (ActivityManagerService.this) {
4338                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4339                                setResultCode(Activity.RESULT_OK);
4340                                return;
4341                            }
4342                        }
4343                    }
4344                }
4345            }
4346        }, pkgFilter);
4347
4348        synchronized (this) {
4349            // Ensure that any processes we had put on hold are now started
4350            // up.
4351            final int NP = mProcessesOnHold.size();
4352            if (NP > 0) {
4353                ArrayList<ProcessRecord> procs =
4354                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4355                for (int ip=0; ip<NP; ip++) {
4356                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4357                            + procs.get(ip));
4358                    startProcessLocked(procs.get(ip), "on-hold", null);
4359                }
4360            }
4361
4362            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4363                // Start looking for apps that are abusing wake locks.
4364                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4365                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4366                // Tell anyone interested that we are done booting!
4367                SystemProperties.set("sys.boot_completed", "1");
4368                SystemProperties.set("dev.bootcomplete", "1");
4369                for (int i=0; i<mStartedUsers.size(); i++) {
4370                    UserStartedState uss = mStartedUsers.valueAt(i);
4371                    if (uss.mState == UserStartedState.STATE_BOOTING) {
4372                        uss.mState = UserStartedState.STATE_RUNNING;
4373                        final int userId = mStartedUsers.keyAt(i);
4374                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4375                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4376                        broadcastIntentLocked(null, null, intent,
4377                                null, null, 0, null, null,
4378                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4379                                false, false, MY_PID, Process.SYSTEM_UID, userId);
4380                    }
4381                }
4382            }
4383        }
4384    }
4385
4386    final void ensureBootCompleted() {
4387        boolean booting;
4388        boolean enableScreen;
4389        synchronized (this) {
4390            booting = mBooting;
4391            mBooting = false;
4392            enableScreen = !mBooted;
4393            mBooted = true;
4394        }
4395
4396        if (booting) {
4397            finishBooting();
4398        }
4399
4400        if (enableScreen) {
4401            enableScreenAfterBoot();
4402        }
4403    }
4404
4405    public final void activityPaused(IBinder token) {
4406        final long origId = Binder.clearCallingIdentity();
4407        mMainStack.activityPaused(token, false);
4408        Binder.restoreCallingIdentity(origId);
4409    }
4410
4411    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4412            CharSequence description) {
4413        if (localLOGV) Slog.v(
4414            TAG, "Activity stopped: token=" + token);
4415
4416        // Refuse possible leaked file descriptors
4417        if (icicle != null && icicle.hasFileDescriptors()) {
4418            throw new IllegalArgumentException("File descriptors passed in Bundle");
4419        }
4420
4421        ActivityRecord r = null;
4422
4423        final long origId = Binder.clearCallingIdentity();
4424
4425        synchronized (this) {
4426            r = mMainStack.isInStackLocked(token);
4427            if (r != null) {
4428                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4429            }
4430        }
4431
4432        if (r != null) {
4433            sendPendingThumbnail(r, null, null, null, false);
4434        }
4435
4436        trimApplications();
4437
4438        Binder.restoreCallingIdentity(origId);
4439    }
4440
4441    public final void activityDestroyed(IBinder token) {
4442        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4443        mMainStack.activityDestroyed(token);
4444    }
4445
4446    public String getCallingPackage(IBinder token) {
4447        synchronized (this) {
4448            ActivityRecord r = getCallingRecordLocked(token);
4449            return r != null && r.app != null ? r.info.packageName : null;
4450        }
4451    }
4452
4453    public ComponentName getCallingActivity(IBinder token) {
4454        synchronized (this) {
4455            ActivityRecord r = getCallingRecordLocked(token);
4456            return r != null ? r.intent.getComponent() : null;
4457        }
4458    }
4459
4460    private ActivityRecord getCallingRecordLocked(IBinder token) {
4461        ActivityRecord r = mMainStack.isInStackLocked(token);
4462        if (r == null) {
4463            return null;
4464        }
4465        return r.resultTo;
4466    }
4467
4468    public ComponentName getActivityClassForToken(IBinder token) {
4469        synchronized(this) {
4470            ActivityRecord r = mMainStack.isInStackLocked(token);
4471            if (r == null) {
4472                return null;
4473            }
4474            return r.intent.getComponent();
4475        }
4476    }
4477
4478    public String getPackageForToken(IBinder token) {
4479        synchronized(this) {
4480            ActivityRecord r = mMainStack.isInStackLocked(token);
4481            if (r == null) {
4482                return null;
4483            }
4484            return r.packageName;
4485        }
4486    }
4487
4488    public IIntentSender getIntentSender(int type,
4489            String packageName, IBinder token, String resultWho,
4490            int requestCode, Intent[] intents, String[] resolvedTypes,
4491            int flags, Bundle options, int userId) {
4492        enforceNotIsolatedCaller("getIntentSender");
4493        // Refuse possible leaked file descriptors
4494        if (intents != null) {
4495            if (intents.length < 1) {
4496                throw new IllegalArgumentException("Intents array length must be >= 1");
4497            }
4498            for (int i=0; i<intents.length; i++) {
4499                Intent intent = intents[i];
4500                if (intent != null) {
4501                    if (intent.hasFileDescriptors()) {
4502                        throw new IllegalArgumentException("File descriptors passed in Intent");
4503                    }
4504                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4505                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4506                        throw new IllegalArgumentException(
4507                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4508                    }
4509                    intents[i] = new Intent(intent);
4510                }
4511            }
4512            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4513                throw new IllegalArgumentException(
4514                        "Intent array length does not match resolvedTypes length");
4515            }
4516        }
4517        if (options != null) {
4518            if (options.hasFileDescriptors()) {
4519                throw new IllegalArgumentException("File descriptors passed in options");
4520            }
4521        }
4522
4523        synchronized(this) {
4524            int callingUid = Binder.getCallingUid();
4525            userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId,
4526                    false, true, "getIntentSender", null);
4527            try {
4528                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4529                    int uid = AppGlobals.getPackageManager()
4530                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4531                    if (!UserHandle.isSameApp(callingUid, uid)) {
4532                        String msg = "Permission Denial: getIntentSender() from pid="
4533                            + Binder.getCallingPid()
4534                            + ", uid=" + Binder.getCallingUid()
4535                            + ", (need uid=" + uid + ")"
4536                            + " is not allowed to send as package " + packageName;
4537                        Slog.w(TAG, msg);
4538                        throw new SecurityException(msg);
4539                    }
4540                }
4541
4542                return getIntentSenderLocked(type, packageName, callingUid, userId,
4543                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4544
4545            } catch (RemoteException e) {
4546                throw new SecurityException(e);
4547            }
4548        }
4549    }
4550
4551    IIntentSender getIntentSenderLocked(int type, String packageName,
4552            int callingUid, int userId, IBinder token, String resultWho,
4553            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4554            Bundle options) {
4555        if (DEBUG_MU)
4556            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4557        ActivityRecord activity = null;
4558        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4559            activity = mMainStack.isInStackLocked(token);
4560            if (activity == null) {
4561                return null;
4562            }
4563            if (activity.finishing) {
4564                return null;
4565            }
4566        }
4567
4568        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4569        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4570        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4571        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4572                |PendingIntent.FLAG_UPDATE_CURRENT);
4573
4574        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4575                type, packageName, activity, resultWho,
4576                requestCode, intents, resolvedTypes, flags, options, userId);
4577        WeakReference<PendingIntentRecord> ref;
4578        ref = mIntentSenderRecords.get(key);
4579        PendingIntentRecord rec = ref != null ? ref.get() : null;
4580        if (rec != null) {
4581            if (!cancelCurrent) {
4582                if (updateCurrent) {
4583                    if (rec.key.requestIntent != null) {
4584                        rec.key.requestIntent.replaceExtras(intents != null ?
4585                                intents[intents.length - 1] : null);
4586                    }
4587                    if (intents != null) {
4588                        intents[intents.length-1] = rec.key.requestIntent;
4589                        rec.key.allIntents = intents;
4590                        rec.key.allResolvedTypes = resolvedTypes;
4591                    } else {
4592                        rec.key.allIntents = null;
4593                        rec.key.allResolvedTypes = null;
4594                    }
4595                }
4596                return rec;
4597            }
4598            rec.canceled = true;
4599            mIntentSenderRecords.remove(key);
4600        }
4601        if (noCreate) {
4602            return rec;
4603        }
4604        rec = new PendingIntentRecord(this, key, callingUid);
4605        mIntentSenderRecords.put(key, rec.ref);
4606        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4607            if (activity.pendingResults == null) {
4608                activity.pendingResults
4609                        = new HashSet<WeakReference<PendingIntentRecord>>();
4610            }
4611            activity.pendingResults.add(rec.ref);
4612        }
4613        return rec;
4614    }
4615
4616    public void cancelIntentSender(IIntentSender sender) {
4617        if (!(sender instanceof PendingIntentRecord)) {
4618            return;
4619        }
4620        synchronized(this) {
4621            PendingIntentRecord rec = (PendingIntentRecord)sender;
4622            try {
4623                int uid = AppGlobals.getPackageManager()
4624                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4625                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4626                    String msg = "Permission Denial: cancelIntentSender() from pid="
4627                        + Binder.getCallingPid()
4628                        + ", uid=" + Binder.getCallingUid()
4629                        + " is not allowed to cancel packges "
4630                        + rec.key.packageName;
4631                    Slog.w(TAG, msg);
4632                    throw new SecurityException(msg);
4633                }
4634            } catch (RemoteException e) {
4635                throw new SecurityException(e);
4636            }
4637            cancelIntentSenderLocked(rec, true);
4638        }
4639    }
4640
4641    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4642        rec.canceled = true;
4643        mIntentSenderRecords.remove(rec.key);
4644        if (cleanActivity && rec.key.activity != null) {
4645            rec.key.activity.pendingResults.remove(rec.ref);
4646        }
4647    }
4648
4649    public String getPackageForIntentSender(IIntentSender pendingResult) {
4650        if (!(pendingResult instanceof PendingIntentRecord)) {
4651            return null;
4652        }
4653        try {
4654            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4655            return res.key.packageName;
4656        } catch (ClassCastException e) {
4657        }
4658        return null;
4659    }
4660
4661    public int getUidForIntentSender(IIntentSender sender) {
4662        if (sender instanceof PendingIntentRecord) {
4663            try {
4664                PendingIntentRecord res = (PendingIntentRecord)sender;
4665                return res.uid;
4666            } catch (ClassCastException e) {
4667            }
4668        }
4669        return -1;
4670    }
4671
4672    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4673        if (!(pendingResult instanceof PendingIntentRecord)) {
4674            return false;
4675        }
4676        try {
4677            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4678            if (res.key.allIntents == null) {
4679                return false;
4680            }
4681            for (int i=0; i<res.key.allIntents.length; i++) {
4682                Intent intent = res.key.allIntents[i];
4683                if (intent.getPackage() != null && intent.getComponent() != null) {
4684                    return false;
4685                }
4686            }
4687            return true;
4688        } catch (ClassCastException e) {
4689        }
4690        return false;
4691    }
4692
4693    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4694        if (!(pendingResult instanceof PendingIntentRecord)) {
4695            return false;
4696        }
4697        try {
4698            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4699            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4700                return true;
4701            }
4702            return false;
4703        } catch (ClassCastException e) {
4704        }
4705        return false;
4706    }
4707
4708    public void setProcessLimit(int max) {
4709        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4710                "setProcessLimit()");
4711        synchronized (this) {
4712            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4713            mProcessLimitOverride = max;
4714        }
4715        trimApplications();
4716    }
4717
4718    public int getProcessLimit() {
4719        synchronized (this) {
4720            return mProcessLimitOverride;
4721        }
4722    }
4723
4724    void foregroundTokenDied(ForegroundToken token) {
4725        synchronized (ActivityManagerService.this) {
4726            synchronized (mPidsSelfLocked) {
4727                ForegroundToken cur
4728                    = mForegroundProcesses.get(token.pid);
4729                if (cur != token) {
4730                    return;
4731                }
4732                mForegroundProcesses.remove(token.pid);
4733                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4734                if (pr == null) {
4735                    return;
4736                }
4737                pr.forcingToForeground = null;
4738                pr.foregroundServices = false;
4739            }
4740            updateOomAdjLocked();
4741        }
4742    }
4743
4744    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4745        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4746                "setProcessForeground()");
4747        synchronized(this) {
4748            boolean changed = false;
4749
4750            synchronized (mPidsSelfLocked) {
4751                ProcessRecord pr = mPidsSelfLocked.get(pid);
4752                if (pr == null && isForeground) {
4753                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4754                    return;
4755                }
4756                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4757                if (oldToken != null) {
4758                    oldToken.token.unlinkToDeath(oldToken, 0);
4759                    mForegroundProcesses.remove(pid);
4760                    if (pr != null) {
4761                        pr.forcingToForeground = null;
4762                    }
4763                    changed = true;
4764                }
4765                if (isForeground && token != null) {
4766                    ForegroundToken newToken = new ForegroundToken() {
4767                        public void binderDied() {
4768                            foregroundTokenDied(this);
4769                        }
4770                    };
4771                    newToken.pid = pid;
4772                    newToken.token = token;
4773                    try {
4774                        token.linkToDeath(newToken, 0);
4775                        mForegroundProcesses.put(pid, newToken);
4776                        pr.forcingToForeground = token;
4777                        changed = true;
4778                    } catch (RemoteException e) {
4779                        // If the process died while doing this, we will later
4780                        // do the cleanup with the process death link.
4781                    }
4782                }
4783            }
4784
4785            if (changed) {
4786                updateOomAdjLocked();
4787            }
4788        }
4789    }
4790
4791    // =========================================================
4792    // PERMISSIONS
4793    // =========================================================
4794
4795    static class PermissionController extends IPermissionController.Stub {
4796        ActivityManagerService mActivityManagerService;
4797        PermissionController(ActivityManagerService activityManagerService) {
4798            mActivityManagerService = activityManagerService;
4799        }
4800
4801        public boolean checkPermission(String permission, int pid, int uid) {
4802            return mActivityManagerService.checkPermission(permission, pid,
4803                    uid) == PackageManager.PERMISSION_GRANTED;
4804        }
4805    }
4806
4807    /**
4808     * This can be called with or without the global lock held.
4809     */
4810    int checkComponentPermission(String permission, int pid, int uid,
4811            int owningUid, boolean exported) {
4812        // We might be performing an operation on behalf of an indirect binder
4813        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4814        // client identity accordingly before proceeding.
4815        Identity tlsIdentity = sCallerIdentity.get();
4816        if (tlsIdentity != null) {
4817            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4818                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4819            uid = tlsIdentity.uid;
4820            pid = tlsIdentity.pid;
4821        }
4822
4823        if (pid == MY_PID) {
4824            return PackageManager.PERMISSION_GRANTED;
4825        }
4826
4827        return ActivityManager.checkComponentPermission(permission, uid,
4828                owningUid, exported);
4829    }
4830
4831    /**
4832     * As the only public entry point for permissions checking, this method
4833     * can enforce the semantic that requesting a check on a null global
4834     * permission is automatically denied.  (Internally a null permission
4835     * string is used when calling {@link #checkComponentPermission} in cases
4836     * when only uid-based security is needed.)
4837     *
4838     * This can be called with or without the global lock held.
4839     */
4840    public int checkPermission(String permission, int pid, int uid) {
4841        if (permission == null) {
4842            return PackageManager.PERMISSION_DENIED;
4843        }
4844        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4845    }
4846
4847    /**
4848     * Binder IPC calls go through the public entry point.
4849     * This can be called with or without the global lock held.
4850     */
4851    int checkCallingPermission(String permission) {
4852        return checkPermission(permission,
4853                Binder.getCallingPid(),
4854                UserHandle.getAppId(Binder.getCallingUid()));
4855    }
4856
4857    /**
4858     * This can be called with or without the global lock held.
4859     */
4860    void enforceCallingPermission(String permission, String func) {
4861        if (checkCallingPermission(permission)
4862                == PackageManager.PERMISSION_GRANTED) {
4863            return;
4864        }
4865
4866        String msg = "Permission Denial: " + func + " from pid="
4867                + Binder.getCallingPid()
4868                + ", uid=" + Binder.getCallingUid()
4869                + " requires " + permission;
4870        Slog.w(TAG, msg);
4871        throw new SecurityException(msg);
4872    }
4873
4874    /**
4875     * Determine if UID is holding permissions required to access {@link Uri} in
4876     * the given {@link ProviderInfo}. Final permission checking is always done
4877     * in {@link ContentProvider}.
4878     */
4879    private final boolean checkHoldingPermissionsLocked(
4880            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4881        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4882                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4883
4884        if (pi.applicationInfo.uid == uid) {
4885            return true;
4886        } else if (!pi.exported) {
4887            return false;
4888        }
4889
4890        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4891        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4892        try {
4893            // check if target holds top-level <provider> permissions
4894            if (!readMet && pi.readPermission != null
4895                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4896                readMet = true;
4897            }
4898            if (!writeMet && pi.writePermission != null
4899                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4900                writeMet = true;
4901            }
4902
4903            // track if unprotected read/write is allowed; any denied
4904            // <path-permission> below removes this ability
4905            boolean allowDefaultRead = pi.readPermission == null;
4906            boolean allowDefaultWrite = pi.writePermission == null;
4907
4908            // check if target holds any <path-permission> that match uri
4909            final PathPermission[] pps = pi.pathPermissions;
4910            if (pps != null) {
4911                final String path = uri.getPath();
4912                int i = pps.length;
4913                while (i > 0 && (!readMet || !writeMet)) {
4914                    i--;
4915                    PathPermission pp = pps[i];
4916                    if (pp.match(path)) {
4917                        if (!readMet) {
4918                            final String pprperm = pp.getReadPermission();
4919                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4920                                    + pprperm + " for " + pp.getPath()
4921                                    + ": match=" + pp.match(path)
4922                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4923                            if (pprperm != null) {
4924                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4925                                    readMet = true;
4926                                } else {
4927                                    allowDefaultRead = false;
4928                                }
4929                            }
4930                        }
4931                        if (!writeMet) {
4932                            final String ppwperm = pp.getWritePermission();
4933                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4934                                    + ppwperm + " for " + pp.getPath()
4935                                    + ": match=" + pp.match(path)
4936                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4937                            if (ppwperm != null) {
4938                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4939                                    writeMet = true;
4940                                } else {
4941                                    allowDefaultWrite = false;
4942                                }
4943                            }
4944                        }
4945                    }
4946                }
4947            }
4948
4949            // grant unprotected <provider> read/write, if not blocked by
4950            // <path-permission> above
4951            if (allowDefaultRead) readMet = true;
4952            if (allowDefaultWrite) writeMet = true;
4953
4954        } catch (RemoteException e) {
4955            return false;
4956        }
4957
4958        return readMet && writeMet;
4959    }
4960
4961    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4962            int modeFlags) {
4963        // Root gets to do everything.
4964        if (uid == 0) {
4965            return true;
4966        }
4967        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4968        if (perms == null) return false;
4969        UriPermission perm = perms.get(uri);
4970        if (perm == null) return false;
4971        return (modeFlags&perm.modeFlags) == modeFlags;
4972    }
4973
4974    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4975        enforceNotIsolatedCaller("checkUriPermission");
4976
4977        // Another redirected-binder-call permissions check as in
4978        // {@link checkComponentPermission}.
4979        Identity tlsIdentity = sCallerIdentity.get();
4980        if (tlsIdentity != null) {
4981            uid = tlsIdentity.uid;
4982            pid = tlsIdentity.pid;
4983        }
4984
4985        uid = UserHandle.getAppId(uid);
4986        // Our own process gets to do everything.
4987        if (pid == MY_PID) {
4988            return PackageManager.PERMISSION_GRANTED;
4989        }
4990        synchronized(this) {
4991            return checkUriPermissionLocked(uri, uid, modeFlags)
4992                    ? PackageManager.PERMISSION_GRANTED
4993                    : PackageManager.PERMISSION_DENIED;
4994        }
4995    }
4996
4997    /**
4998     * Check if the targetPkg can be granted permission to access uri by
4999     * the callingUid using the given modeFlags.  Throws a security exception
5000     * if callingUid is not allowed to do this.  Returns the uid of the target
5001     * if the URI permission grant should be performed; returns -1 if it is not
5002     * needed (for example targetPkg already has permission to access the URI).
5003     * If you already know the uid of the target, you can supply it in
5004     * lastTargetUid else set that to -1.
5005     */
5006    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5007            Uri uri, int modeFlags, int lastTargetUid) {
5008        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5009                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5010        if (modeFlags == 0) {
5011            return -1;
5012        }
5013
5014        if (targetPkg != null) {
5015            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5016                    "Checking grant " + targetPkg + " permission to " + uri);
5017        }
5018
5019        final IPackageManager pm = AppGlobals.getPackageManager();
5020
5021        // If this is not a content: uri, we can't do anything with it.
5022        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5023            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5024                    "Can't grant URI permission for non-content URI: " + uri);
5025            return -1;
5026        }
5027
5028        String name = uri.getAuthority();
5029        ProviderInfo pi = null;
5030        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5031                UserHandle.getUserId(callingUid));
5032        if (cpr != null) {
5033            pi = cpr.info;
5034        } else {
5035            try {
5036                pi = pm.resolveContentProvider(name,
5037                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid));
5038            } catch (RemoteException ex) {
5039            }
5040        }
5041        if (pi == null) {
5042            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5043            return -1;
5044        }
5045
5046        int targetUid = lastTargetUid;
5047        if (targetUid < 0 && targetPkg != null) {
5048            try {
5049                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5050                if (targetUid < 0) {
5051                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5052                            "Can't grant URI permission no uid for: " + targetPkg);
5053                    return -1;
5054                }
5055            } catch (RemoteException ex) {
5056                return -1;
5057            }
5058        }
5059
5060        if (targetUid >= 0) {
5061            // First...  does the target actually need this permission?
5062            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5063                // No need to grant the target this permission.
5064                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5065                        "Target " + targetPkg + " already has full permission to " + uri);
5066                return -1;
5067            }
5068        } else {
5069            // First...  there is no target package, so can anyone access it?
5070            boolean allowed = pi.exported;
5071            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5072                if (pi.readPermission != null) {
5073                    allowed = false;
5074                }
5075            }
5076            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5077                if (pi.writePermission != null) {
5078                    allowed = false;
5079                }
5080            }
5081            if (allowed) {
5082                return -1;
5083            }
5084        }
5085
5086        // Second...  is the provider allowing granting of URI permissions?
5087        if (!pi.grantUriPermissions) {
5088            throw new SecurityException("Provider " + pi.packageName
5089                    + "/" + pi.name
5090                    + " does not allow granting of Uri permissions (uri "
5091                    + uri + ")");
5092        }
5093        if (pi.uriPermissionPatterns != null) {
5094            final int N = pi.uriPermissionPatterns.length;
5095            boolean allowed = false;
5096            for (int i=0; i<N; i++) {
5097                if (pi.uriPermissionPatterns[i] != null
5098                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5099                    allowed = true;
5100                    break;
5101                }
5102            }
5103            if (!allowed) {
5104                throw new SecurityException("Provider " + pi.packageName
5105                        + "/" + pi.name
5106                        + " does not allow granting of permission to path of Uri "
5107                        + uri);
5108            }
5109        }
5110
5111        // Third...  does the caller itself have permission to access
5112        // this uri?
5113        if (callingUid != Process.myUid()) {
5114            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5115                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5116                    throw new SecurityException("Uid " + callingUid
5117                            + " does not have permission to uri " + uri);
5118                }
5119            }
5120        }
5121
5122        return targetUid;
5123    }
5124
5125    public int checkGrantUriPermission(int callingUid, String targetPkg,
5126            Uri uri, int modeFlags) {
5127        enforceNotIsolatedCaller("checkGrantUriPermission");
5128        synchronized(this) {
5129            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5130        }
5131    }
5132
5133    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5134            Uri uri, int modeFlags, UriPermissionOwner owner) {
5135        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5136                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5137        if (modeFlags == 0) {
5138            return;
5139        }
5140
5141        // So here we are: the caller has the assumed permission
5142        // to the uri, and the target doesn't.  Let's now give this to
5143        // the target.
5144
5145        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5146                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5147
5148        HashMap<Uri, UriPermission> targetUris
5149                = mGrantedUriPermissions.get(targetUid);
5150        if (targetUris == null) {
5151            targetUris = new HashMap<Uri, UriPermission>();
5152            mGrantedUriPermissions.put(targetUid, targetUris);
5153        }
5154
5155        UriPermission perm = targetUris.get(uri);
5156        if (perm == null) {
5157            perm = new UriPermission(targetUid, uri);
5158            targetUris.put(uri, perm);
5159        }
5160
5161        perm.modeFlags |= modeFlags;
5162        if (owner == null) {
5163            perm.globalModeFlags |= modeFlags;
5164        } else {
5165            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5166                 perm.readOwners.add(owner);
5167                 owner.addReadPermission(perm);
5168            }
5169            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5170                 perm.writeOwners.add(owner);
5171                 owner.addWritePermission(perm);
5172            }
5173        }
5174    }
5175
5176    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5177            int modeFlags, UriPermissionOwner owner) {
5178        if (targetPkg == null) {
5179            throw new NullPointerException("targetPkg");
5180        }
5181
5182        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5183        if (targetUid < 0) {
5184            return;
5185        }
5186
5187        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5188    }
5189
5190    static class NeededUriGrants extends ArrayList<Uri> {
5191        final String targetPkg;
5192        final int targetUid;
5193        final int flags;
5194
5195        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5196            targetPkg = _targetPkg;
5197            targetUid = _targetUid;
5198            flags = _flags;
5199        }
5200    }
5201
5202    /**
5203     * Like checkGrantUriPermissionLocked, but takes an Intent.
5204     */
5205    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5206            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5207        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5208                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5209                + " clip=" + (intent != null ? intent.getClipData() : null)
5210                + " from " + intent + "; flags=0x"
5211                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5212
5213        if (targetPkg == null) {
5214            throw new NullPointerException("targetPkg");
5215        }
5216
5217        if (intent == null) {
5218            return null;
5219        }
5220        Uri data = intent.getData();
5221        ClipData clip = intent.getClipData();
5222        if (data == null && clip == null) {
5223            return null;
5224        }
5225        if (data != null) {
5226            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5227                mode, needed != null ? needed.targetUid : -1);
5228            if (target > 0) {
5229                if (needed == null) {
5230                    needed = new NeededUriGrants(targetPkg, target, mode);
5231                }
5232                needed.add(data);
5233            }
5234        }
5235        if (clip != null) {
5236            for (int i=0; i<clip.getItemCount(); i++) {
5237                Uri uri = clip.getItemAt(i).getUri();
5238                if (uri != null) {
5239                    int target = -1;
5240                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5241                            mode, needed != null ? needed.targetUid : -1);
5242                    if (target > 0) {
5243                        if (needed == null) {
5244                            needed = new NeededUriGrants(targetPkg, target, mode);
5245                        }
5246                        needed.add(uri);
5247                    }
5248                } else {
5249                    Intent clipIntent = clip.getItemAt(i).getIntent();
5250                    if (clipIntent != null) {
5251                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5252                                callingUid, targetPkg, clipIntent, mode, needed);
5253                        if (newNeeded != null) {
5254                            needed = newNeeded;
5255                        }
5256                    }
5257                }
5258            }
5259        }
5260
5261        return needed;
5262    }
5263
5264    /**
5265     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5266     */
5267    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5268            UriPermissionOwner owner) {
5269        if (needed != null) {
5270            for (int i=0; i<needed.size(); i++) {
5271                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5272                        needed.get(i), needed.flags, owner);
5273            }
5274        }
5275    }
5276
5277    void grantUriPermissionFromIntentLocked(int callingUid,
5278            String targetPkg, Intent intent, UriPermissionOwner owner) {
5279        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5280                intent, intent != null ? intent.getFlags() : 0, null);
5281        if (needed == null) {
5282            return;
5283        }
5284
5285        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5286    }
5287
5288    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5289            Uri uri, int modeFlags) {
5290        enforceNotIsolatedCaller("grantUriPermission");
5291        synchronized(this) {
5292            final ProcessRecord r = getRecordForAppLocked(caller);
5293            if (r == null) {
5294                throw new SecurityException("Unable to find app for caller "
5295                        + caller
5296                        + " when granting permission to uri " + uri);
5297            }
5298            if (targetPkg == null) {
5299                throw new IllegalArgumentException("null target");
5300            }
5301            if (uri == null) {
5302                throw new IllegalArgumentException("null uri");
5303            }
5304
5305            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5306                    null);
5307        }
5308    }
5309
5310    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5311        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5312                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5313            HashMap<Uri, UriPermission> perms
5314                    = mGrantedUriPermissions.get(perm.uid);
5315            if (perms != null) {
5316                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5317                        "Removing " + perm.uid + " permission to " + perm.uri);
5318                perms.remove(perm.uri);
5319                if (perms.size() == 0) {
5320                    mGrantedUriPermissions.remove(perm.uid);
5321                }
5322            }
5323        }
5324    }
5325
5326    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5327            int modeFlags) {
5328        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5329                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5330        if (modeFlags == 0) {
5331            return;
5332        }
5333
5334        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5335                "Revoking all granted permissions to " + uri);
5336
5337        final IPackageManager pm = AppGlobals.getPackageManager();
5338
5339        final String authority = uri.getAuthority();
5340        ProviderInfo pi = null;
5341        int userId = UserHandle.getUserId(callingUid);
5342        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5343        if (cpr != null) {
5344            pi = cpr.info;
5345        } else {
5346            try {
5347                pi = pm.resolveContentProvider(authority,
5348                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5349            } catch (RemoteException ex) {
5350            }
5351        }
5352        if (pi == null) {
5353            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5354            return;
5355        }
5356
5357        // Does the caller have this permission on the URI?
5358        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5359            // Right now, if you are not the original owner of the permission,
5360            // you are not allowed to revoke it.
5361            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5362                throw new SecurityException("Uid " + callingUid
5363                        + " does not have permission to uri " + uri);
5364            //}
5365        }
5366
5367        // Go through all of the permissions and remove any that match.
5368        final List<String> SEGMENTS = uri.getPathSegments();
5369        if (SEGMENTS != null) {
5370            final int NS = SEGMENTS.size();
5371            int N = mGrantedUriPermissions.size();
5372            for (int i=0; i<N; i++) {
5373                HashMap<Uri, UriPermission> perms
5374                        = mGrantedUriPermissions.valueAt(i);
5375                Iterator<UriPermission> it = perms.values().iterator();
5376            toploop:
5377                while (it.hasNext()) {
5378                    UriPermission perm = it.next();
5379                    Uri targetUri = perm.uri;
5380                    if (!authority.equals(targetUri.getAuthority())) {
5381                        continue;
5382                    }
5383                    List<String> targetSegments = targetUri.getPathSegments();
5384                    if (targetSegments == null) {
5385                        continue;
5386                    }
5387                    if (targetSegments.size() < NS) {
5388                        continue;
5389                    }
5390                    for (int j=0; j<NS; j++) {
5391                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5392                            continue toploop;
5393                        }
5394                    }
5395                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5396                            "Revoking " + perm.uid + " permission to " + perm.uri);
5397                    perm.clearModes(modeFlags);
5398                    if (perm.modeFlags == 0) {
5399                        it.remove();
5400                    }
5401                }
5402                if (perms.size() == 0) {
5403                    mGrantedUriPermissions.remove(
5404                            mGrantedUriPermissions.keyAt(i));
5405                    N--;
5406                    i--;
5407                }
5408            }
5409        }
5410    }
5411
5412    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5413            int modeFlags) {
5414        enforceNotIsolatedCaller("revokeUriPermission");
5415        synchronized(this) {
5416            final ProcessRecord r = getRecordForAppLocked(caller);
5417            if (r == null) {
5418                throw new SecurityException("Unable to find app for caller "
5419                        + caller
5420                        + " when revoking permission to uri " + uri);
5421            }
5422            if (uri == null) {
5423                Slog.w(TAG, "revokeUriPermission: null uri");
5424                return;
5425            }
5426
5427            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5428                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5429            if (modeFlags == 0) {
5430                return;
5431            }
5432
5433            final IPackageManager pm = AppGlobals.getPackageManager();
5434
5435            final String authority = uri.getAuthority();
5436            ProviderInfo pi = null;
5437            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5438            if (cpr != null) {
5439                pi = cpr.info;
5440            } else {
5441                try {
5442                    pi = pm.resolveContentProvider(authority,
5443                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5444                } catch (RemoteException ex) {
5445                }
5446            }
5447            if (pi == null) {
5448                Slog.w(TAG, "No content provider found for permission revoke: "
5449                        + uri.toSafeString());
5450                return;
5451            }
5452
5453            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5454        }
5455    }
5456
5457    @Override
5458    public IBinder newUriPermissionOwner(String name) {
5459        enforceNotIsolatedCaller("newUriPermissionOwner");
5460        synchronized(this) {
5461            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5462            return owner.getExternalTokenLocked();
5463        }
5464    }
5465
5466    @Override
5467    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5468            Uri uri, int modeFlags) {
5469        synchronized(this) {
5470            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5471            if (owner == null) {
5472                throw new IllegalArgumentException("Unknown owner: " + token);
5473            }
5474            if (fromUid != Binder.getCallingUid()) {
5475                if (Binder.getCallingUid() != Process.myUid()) {
5476                    // Only system code can grant URI permissions on behalf
5477                    // of other users.
5478                    throw new SecurityException("nice try");
5479                }
5480            }
5481            if (targetPkg == null) {
5482                throw new IllegalArgumentException("null target");
5483            }
5484            if (uri == null) {
5485                throw new IllegalArgumentException("null uri");
5486            }
5487
5488            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5489        }
5490    }
5491
5492    @Override
5493    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5494        synchronized(this) {
5495            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5496            if (owner == null) {
5497                throw new IllegalArgumentException("Unknown owner: " + token);
5498            }
5499
5500            if (uri == null) {
5501                owner.removeUriPermissionsLocked(mode);
5502            } else {
5503                owner.removeUriPermissionLocked(uri, mode);
5504            }
5505        }
5506    }
5507
5508    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5509        synchronized (this) {
5510            ProcessRecord app =
5511                who != null ? getRecordForAppLocked(who) : null;
5512            if (app == null) return;
5513
5514            Message msg = Message.obtain();
5515            msg.what = WAIT_FOR_DEBUGGER_MSG;
5516            msg.obj = app;
5517            msg.arg1 = waiting ? 1 : 0;
5518            mHandler.sendMessage(msg);
5519        }
5520    }
5521
5522    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5523        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5524        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5525        outInfo.availMem = Process.getFreeMemory();
5526        outInfo.totalMem = Process.getTotalMemory();
5527        outInfo.threshold = homeAppMem;
5528        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5529        outInfo.hiddenAppThreshold = hiddenAppMem;
5530        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5531                ProcessList.SERVICE_ADJ);
5532        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5533                ProcessList.VISIBLE_APP_ADJ);
5534        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5535                ProcessList.FOREGROUND_APP_ADJ);
5536    }
5537
5538    // =========================================================
5539    // TASK MANAGEMENT
5540    // =========================================================
5541
5542    public List getTasks(int maxNum, int flags,
5543                         IThumbnailReceiver receiver) {
5544        ArrayList list = new ArrayList();
5545
5546        PendingThumbnailsRecord pending = null;
5547        IApplicationThread topThumbnail = null;
5548        ActivityRecord topRecord = null;
5549
5550        synchronized(this) {
5551            if (localLOGV) Slog.v(
5552                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5553                + ", receiver=" + receiver);
5554
5555            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5556                    != PackageManager.PERMISSION_GRANTED) {
5557                if (receiver != null) {
5558                    // If the caller wants to wait for pending thumbnails,
5559                    // it ain't gonna get them.
5560                    try {
5561                        receiver.finished();
5562                    } catch (RemoteException ex) {
5563                    }
5564                }
5565                String msg = "Permission Denial: getTasks() from pid="
5566                        + Binder.getCallingPid()
5567                        + ", uid=" + Binder.getCallingUid()
5568                        + " requires " + android.Manifest.permission.GET_TASKS;
5569                Slog.w(TAG, msg);
5570                throw new SecurityException(msg);
5571            }
5572
5573            int pos = mMainStack.mHistory.size()-1;
5574            ActivityRecord next =
5575                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5576            ActivityRecord top = null;
5577            TaskRecord curTask = null;
5578            int numActivities = 0;
5579            int numRunning = 0;
5580            while (pos >= 0 && maxNum > 0) {
5581                final ActivityRecord r = next;
5582                pos--;
5583                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5584
5585                // Initialize state for next task if needed.
5586                if (top == null ||
5587                        (top.state == ActivityState.INITIALIZING
5588                            && top.task == r.task)) {
5589                    top = r;
5590                    curTask = r.task;
5591                    numActivities = numRunning = 0;
5592                }
5593
5594                // Add 'r' into the current task.
5595                numActivities++;
5596                if (r.app != null && r.app.thread != null) {
5597                    numRunning++;
5598                }
5599
5600                if (localLOGV) Slog.v(
5601                    TAG, r.intent.getComponent().flattenToShortString()
5602                    + ": task=" + r.task);
5603
5604                // If the next one is a different task, generate a new
5605                // TaskInfo entry for what we have.
5606                if (next == null || next.task != curTask) {
5607                    ActivityManager.RunningTaskInfo ci
5608                            = new ActivityManager.RunningTaskInfo();
5609                    ci.id = curTask.taskId;
5610                    ci.baseActivity = r.intent.getComponent();
5611                    ci.topActivity = top.intent.getComponent();
5612                    if (top.thumbHolder != null) {
5613                        ci.description = top.thumbHolder.lastDescription;
5614                    }
5615                    ci.numActivities = numActivities;
5616                    ci.numRunning = numRunning;
5617                    //System.out.println(
5618                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5619                    if (ci.thumbnail == null && receiver != null) {
5620                        if (localLOGV) Slog.v(
5621                            TAG, "State=" + top.state + "Idle=" + top.idle
5622                            + " app=" + top.app
5623                            + " thr=" + (top.app != null ? top.app.thread : null));
5624                        if (top.state == ActivityState.RESUMED
5625                                || top.state == ActivityState.PAUSING) {
5626                            if (top.idle && top.app != null
5627                                && top.app.thread != null) {
5628                                topRecord = top;
5629                                topThumbnail = top.app.thread;
5630                            } else {
5631                                top.thumbnailNeeded = true;
5632                            }
5633                        }
5634                        if (pending == null) {
5635                            pending = new PendingThumbnailsRecord(receiver);
5636                        }
5637                        pending.pendingRecords.add(top);
5638                    }
5639                    list.add(ci);
5640                    maxNum--;
5641                    top = null;
5642                }
5643            }
5644
5645            if (pending != null) {
5646                mPendingThumbnails.add(pending);
5647            }
5648        }
5649
5650        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5651
5652        if (topThumbnail != null) {
5653            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5654            try {
5655                topThumbnail.requestThumbnail(topRecord.appToken);
5656            } catch (Exception e) {
5657                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5658                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5659            }
5660        }
5661
5662        if (pending == null && receiver != null) {
5663            // In this case all thumbnails were available and the client
5664            // is being asked to be told when the remaining ones come in...
5665            // which is unusually, since the top-most currently running
5666            // activity should never have a canned thumbnail!  Oh well.
5667            try {
5668                receiver.finished();
5669            } catch (RemoteException ex) {
5670            }
5671        }
5672
5673        return list;
5674    }
5675
5676    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5677            int flags, int userId) {
5678        final int callingUid = Binder.getCallingUid();
5679        if (userId != UserHandle.getCallingUserId()) {
5680            // Check if the caller is holding permissions for cross-user requests.
5681            if (checkComponentPermission(
5682                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5683                    Binder.getCallingPid(), callingUid, -1, true)
5684                    != PackageManager.PERMISSION_GRANTED) {
5685                String msg = "Permission Denial: "
5686                        + "Request to get recent tasks for user " + userId
5687                        + " but is calling from user " + UserHandle.getUserId(callingUid)
5688                        + "; this requires "
5689                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5690                Slog.w(TAG, msg);
5691                throw new SecurityException(msg);
5692            } else {
5693                if (userId == UserHandle.USER_CURRENT) {
5694                    userId = mCurrentUserId;
5695                }
5696            }
5697        }
5698
5699        synchronized (this) {
5700            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5701                    "getRecentTasks()");
5702            final boolean detailed = checkCallingPermission(
5703                    android.Manifest.permission.GET_DETAILED_TASKS)
5704                    == PackageManager.PERMISSION_GRANTED;
5705
5706            IPackageManager pm = AppGlobals.getPackageManager();
5707
5708            final int N = mRecentTasks.size();
5709            ArrayList<ActivityManager.RecentTaskInfo> res
5710                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5711                            maxNum < N ? maxNum : N);
5712            for (int i=0; i<N && maxNum > 0; i++) {
5713                TaskRecord tr = mRecentTasks.get(i);
5714                // Only add calling user's recent tasks
5715                if (tr.userId != userId) continue;
5716                // Return the entry if desired by the caller.  We always return
5717                // the first entry, because callers always expect this to be the
5718                // foreground app.  We may filter others if the caller has
5719                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5720                // we should exclude the entry.
5721
5722                if (i == 0
5723                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5724                        || (tr.intent == null)
5725                        || ((tr.intent.getFlags()
5726                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5727                    ActivityManager.RecentTaskInfo rti
5728                            = new ActivityManager.RecentTaskInfo();
5729                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5730                    rti.persistentId = tr.taskId;
5731                    rti.baseIntent = new Intent(
5732                            tr.intent != null ? tr.intent : tr.affinityIntent);
5733                    if (!detailed) {
5734                        rti.baseIntent.replaceExtras((Bundle)null);
5735                    }
5736                    rti.origActivity = tr.origActivity;
5737                    rti.description = tr.lastDescription;
5738
5739                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5740                        // Check whether this activity is currently available.
5741                        try {
5742                            if (rti.origActivity != null) {
5743                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5744                                        == null) {
5745                                    continue;
5746                                }
5747                            } else if (rti.baseIntent != null) {
5748                                if (pm.queryIntentActivities(rti.baseIntent,
5749                                        null, 0, userId) == null) {
5750                                    continue;
5751                                }
5752                            }
5753                        } catch (RemoteException e) {
5754                            // Will never happen.
5755                        }
5756                    }
5757
5758                    res.add(rti);
5759                    maxNum--;
5760                }
5761            }
5762            return res;
5763        }
5764    }
5765
5766    private TaskRecord taskForIdLocked(int id) {
5767        final int N = mRecentTasks.size();
5768        for (int i=0; i<N; i++) {
5769            TaskRecord tr = mRecentTasks.get(i);
5770            if (tr.taskId == id) {
5771                return tr;
5772            }
5773        }
5774        return null;
5775    }
5776
5777    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5778        synchronized (this) {
5779            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5780                    "getTaskThumbnails()");
5781            TaskRecord tr = taskForIdLocked(id);
5782            if (tr != null) {
5783                return mMainStack.getTaskThumbnailsLocked(tr);
5784            }
5785        }
5786        return null;
5787    }
5788
5789    public boolean removeSubTask(int taskId, int subTaskIndex) {
5790        synchronized (this) {
5791            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5792                    "removeSubTask()");
5793            long ident = Binder.clearCallingIdentity();
5794            try {
5795                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5796                        true) != null;
5797            } finally {
5798                Binder.restoreCallingIdentity(ident);
5799            }
5800        }
5801    }
5802
5803    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5804        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5805        Intent baseIntent = new Intent(
5806                tr.intent != null ? tr.intent : tr.affinityIntent);
5807        ComponentName component = baseIntent.getComponent();
5808        if (component == null) {
5809            Slog.w(TAG, "Now component for base intent of task: " + tr);
5810            return;
5811        }
5812
5813        // Find any running services associated with this app.
5814        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5815
5816        if (killProcesses) {
5817            // Find any running processes associated with this app.
5818            final String pkg = component.getPackageName();
5819            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5820            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5821            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5822                for (int i=0; i<uids.size(); i++) {
5823                    ProcessRecord proc = uids.valueAt(i);
5824                    if (proc.userId != tr.userId) {
5825                        continue;
5826                    }
5827                    if (!proc.pkgList.contains(pkg)) {
5828                        continue;
5829                    }
5830                    procs.add(proc);
5831                }
5832            }
5833
5834            // Kill the running processes.
5835            for (int i=0; i<procs.size(); i++) {
5836                ProcessRecord pr = procs.get(i);
5837                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5838                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5839                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5840                            pr.processName, pr.setAdj, "remove task");
5841                    pr.killedBackground = true;
5842                    Process.killProcessQuiet(pr.pid);
5843                } else {
5844                    pr.waitingToKill = "remove task";
5845                }
5846            }
5847        }
5848    }
5849
5850    public boolean removeTask(int taskId, int flags) {
5851        synchronized (this) {
5852            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5853                    "removeTask()");
5854            long ident = Binder.clearCallingIdentity();
5855            try {
5856                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5857                        false);
5858                if (r != null) {
5859                    mRecentTasks.remove(r.task);
5860                    cleanUpRemovedTaskLocked(r.task, flags);
5861                    return true;
5862                } else {
5863                    TaskRecord tr = null;
5864                    int i=0;
5865                    while (i < mRecentTasks.size()) {
5866                        TaskRecord t = mRecentTasks.get(i);
5867                        if (t.taskId == taskId) {
5868                            tr = t;
5869                            break;
5870                        }
5871                        i++;
5872                    }
5873                    if (tr != null) {
5874                        if (tr.numActivities <= 0) {
5875                            // Caller is just removing a recent task that is
5876                            // not actively running.  That is easy!
5877                            mRecentTasks.remove(i);
5878                            cleanUpRemovedTaskLocked(tr, flags);
5879                            return true;
5880                        } else {
5881                            Slog.w(TAG, "removeTask: task " + taskId
5882                                    + " does not have activities to remove, "
5883                                    + " but numActivities=" + tr.numActivities
5884                                    + ": " + tr);
5885                        }
5886                    }
5887                }
5888            } finally {
5889                Binder.restoreCallingIdentity(ident);
5890            }
5891        }
5892        return false;
5893    }
5894
5895    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5896        int j;
5897        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5898        TaskRecord jt = startTask;
5899
5900        // First look backwards
5901        for (j=startIndex-1; j>=0; j--) {
5902            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5903            if (r.task != jt) {
5904                jt = r.task;
5905                if (affinity.equals(jt.affinity)) {
5906                    return j;
5907                }
5908            }
5909        }
5910
5911        // Now look forwards
5912        final int N = mMainStack.mHistory.size();
5913        jt = startTask;
5914        for (j=startIndex+1; j<N; j++) {
5915            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5916            if (r.task != jt) {
5917                if (affinity.equals(jt.affinity)) {
5918                    return j;
5919                }
5920                jt = r.task;
5921            }
5922        }
5923
5924        // Might it be at the top?
5925        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5926            return N-1;
5927        }
5928
5929        return -1;
5930    }
5931
5932    /**
5933     * TODO: Add mController hook
5934     */
5935    public void moveTaskToFront(int task, int flags, Bundle options) {
5936        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5937                "moveTaskToFront()");
5938
5939        synchronized(this) {
5940            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5941                    Binder.getCallingUid(), "Task to front")) {
5942                ActivityOptions.abort(options);
5943                return;
5944            }
5945            final long origId = Binder.clearCallingIdentity();
5946            try {
5947                TaskRecord tr = taskForIdLocked(task);
5948                if (tr != null) {
5949                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5950                        mMainStack.mUserLeaving = true;
5951                    }
5952                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5953                        // Caller wants the home activity moved with it.  To accomplish this,
5954                        // we'll just move the home task to the top first.
5955                        mMainStack.moveHomeToFrontLocked();
5956                    }
5957                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5958                    return;
5959                }
5960                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5961                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5962                    if (hr.task.taskId == task) {
5963                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5964                            mMainStack.mUserLeaving = true;
5965                        }
5966                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5967                            // Caller wants the home activity moved with it.  To accomplish this,
5968                            // we'll just move the home task to the top first.
5969                            mMainStack.moveHomeToFrontLocked();
5970                        }
5971                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5972                        return;
5973                    }
5974                }
5975            } finally {
5976                Binder.restoreCallingIdentity(origId);
5977            }
5978            ActivityOptions.abort(options);
5979        }
5980    }
5981
5982    public void moveTaskToBack(int task) {
5983        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5984                "moveTaskToBack()");
5985
5986        synchronized(this) {
5987            if (mMainStack.mResumedActivity != null
5988                    && mMainStack.mResumedActivity.task.taskId == task) {
5989                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5990                        Binder.getCallingUid(), "Task to back")) {
5991                    return;
5992                }
5993            }
5994            final long origId = Binder.clearCallingIdentity();
5995            mMainStack.moveTaskToBackLocked(task, null);
5996            Binder.restoreCallingIdentity(origId);
5997        }
5998    }
5999
6000    /**
6001     * Moves an activity, and all of the other activities within the same task, to the bottom
6002     * of the history stack.  The activity's order within the task is unchanged.
6003     *
6004     * @param token A reference to the activity we wish to move
6005     * @param nonRoot If false then this only works if the activity is the root
6006     *                of a task; if true it will work for any activity in a task.
6007     * @return Returns true if the move completed, false if not.
6008     */
6009    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6010        enforceNotIsolatedCaller("moveActivityTaskToBack");
6011        synchronized(this) {
6012            final long origId = Binder.clearCallingIdentity();
6013            int taskId = getTaskForActivityLocked(token, !nonRoot);
6014            if (taskId >= 0) {
6015                return mMainStack.moveTaskToBackLocked(taskId, null);
6016            }
6017            Binder.restoreCallingIdentity(origId);
6018        }
6019        return false;
6020    }
6021
6022    public void moveTaskBackwards(int task) {
6023        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6024                "moveTaskBackwards()");
6025
6026        synchronized(this) {
6027            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6028                    Binder.getCallingUid(), "Task backwards")) {
6029                return;
6030            }
6031            final long origId = Binder.clearCallingIdentity();
6032            moveTaskBackwardsLocked(task);
6033            Binder.restoreCallingIdentity(origId);
6034        }
6035    }
6036
6037    private final void moveTaskBackwardsLocked(int task) {
6038        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
6039    }
6040
6041    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6042        synchronized(this) {
6043            return getTaskForActivityLocked(token, onlyRoot);
6044        }
6045    }
6046
6047    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6048        final int N = mMainStack.mHistory.size();
6049        TaskRecord lastTask = null;
6050        for (int i=0; i<N; i++) {
6051            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6052            if (r.appToken == token) {
6053                if (!onlyRoot || lastTask != r.task) {
6054                    return r.task.taskId;
6055                }
6056                return -1;
6057            }
6058            lastTask = r.task;
6059        }
6060
6061        return -1;
6062    }
6063
6064    // =========================================================
6065    // THUMBNAILS
6066    // =========================================================
6067
6068    public void reportThumbnail(IBinder token,
6069            Bitmap thumbnail, CharSequence description) {
6070        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6071        final long origId = Binder.clearCallingIdentity();
6072        sendPendingThumbnail(null, token, thumbnail, description, true);
6073        Binder.restoreCallingIdentity(origId);
6074    }
6075
6076    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6077            Bitmap thumbnail, CharSequence description, boolean always) {
6078        TaskRecord task = null;
6079        ArrayList receivers = null;
6080
6081        //System.out.println("Send pending thumbnail: " + r);
6082
6083        synchronized(this) {
6084            if (r == null) {
6085                r = mMainStack.isInStackLocked(token);
6086                if (r == null) {
6087                    return;
6088                }
6089            }
6090            if (thumbnail == null && r.thumbHolder != null) {
6091                thumbnail = r.thumbHolder.lastThumbnail;
6092                description = r.thumbHolder.lastDescription;
6093            }
6094            if (thumbnail == null && !always) {
6095                // If there is no thumbnail, and this entry is not actually
6096                // going away, then abort for now and pick up the next
6097                // thumbnail we get.
6098                return;
6099            }
6100            task = r.task;
6101
6102            int N = mPendingThumbnails.size();
6103            int i=0;
6104            while (i<N) {
6105                PendingThumbnailsRecord pr =
6106                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6107                //System.out.println("Looking in " + pr.pendingRecords);
6108                if (pr.pendingRecords.remove(r)) {
6109                    if (receivers == null) {
6110                        receivers = new ArrayList();
6111                    }
6112                    receivers.add(pr);
6113                    if (pr.pendingRecords.size() == 0) {
6114                        pr.finished = true;
6115                        mPendingThumbnails.remove(i);
6116                        N--;
6117                        continue;
6118                    }
6119                }
6120                i++;
6121            }
6122        }
6123
6124        if (receivers != null) {
6125            final int N = receivers.size();
6126            for (int i=0; i<N; i++) {
6127                try {
6128                    PendingThumbnailsRecord pr =
6129                        (PendingThumbnailsRecord)receivers.get(i);
6130                    pr.receiver.newThumbnail(
6131                        task != null ? task.taskId : -1, thumbnail, description);
6132                    if (pr.finished) {
6133                        pr.receiver.finished();
6134                    }
6135                } catch (Exception e) {
6136                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6137                }
6138            }
6139        }
6140    }
6141
6142    // =========================================================
6143    // CONTENT PROVIDERS
6144    // =========================================================
6145
6146    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6147        List<ProviderInfo> providers = null;
6148        try {
6149            providers = AppGlobals.getPackageManager().
6150                queryContentProviders(app.processName, app.uid,
6151                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6152        } catch (RemoteException ex) {
6153        }
6154        if (DEBUG_MU)
6155            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6156        int userId = app.userId;
6157        if (providers != null) {
6158            int N = providers.size();
6159            for (int i=0; i<N; i++) {
6160                ProviderInfo cpi =
6161                    (ProviderInfo)providers.get(i);
6162                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6163                        cpi.name, cpi.flags);
6164                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6165                    // This is a singleton provider, but a user besides the
6166                    // default user is asking to initialize a process it runs
6167                    // in...  well, no, it doesn't actually run in this process,
6168                    // it runs in the process of the default user.  Get rid of it.
6169                    providers.remove(i);
6170                    N--;
6171                    continue;
6172                }
6173
6174                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6175                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6176                if (cpr == null) {
6177                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6178                    mProviderMap.putProviderByClass(comp, cpr);
6179                }
6180                if (DEBUG_MU)
6181                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6182                app.pubProviders.put(cpi.name, cpr);
6183                app.addPackage(cpi.applicationInfo.packageName);
6184                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6185            }
6186        }
6187        return providers;
6188    }
6189
6190    /**
6191     * Check if {@link ProcessRecord} has a possible chance at accessing the
6192     * given {@link ProviderInfo}. Final permission checking is always done
6193     * in {@link ContentProvider}.
6194     */
6195    private final String checkContentProviderPermissionLocked(
6196            ProviderInfo cpi, ProcessRecord r) {
6197        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6198        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6199        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6200                cpi.applicationInfo.uid, cpi.exported)
6201                == PackageManager.PERMISSION_GRANTED) {
6202            return null;
6203        }
6204        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6205                cpi.applicationInfo.uid, cpi.exported)
6206                == PackageManager.PERMISSION_GRANTED) {
6207            return null;
6208        }
6209
6210        PathPermission[] pps = cpi.pathPermissions;
6211        if (pps != null) {
6212            int i = pps.length;
6213            while (i > 0) {
6214                i--;
6215                PathPermission pp = pps[i];
6216                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6217                        cpi.applicationInfo.uid, cpi.exported)
6218                        == PackageManager.PERMISSION_GRANTED) {
6219                    return null;
6220                }
6221                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6222                        cpi.applicationInfo.uid, cpi.exported)
6223                        == PackageManager.PERMISSION_GRANTED) {
6224                    return null;
6225                }
6226            }
6227        }
6228
6229        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6230        if (perms != null) {
6231            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6232                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6233                    return null;
6234                }
6235            }
6236        }
6237
6238        String msg;
6239        if (!cpi.exported) {
6240            msg = "Permission Denial: opening provider " + cpi.name
6241                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6242                    + ", uid=" + callingUid + ") that is not exported from uid "
6243                    + cpi.applicationInfo.uid;
6244        } else {
6245            msg = "Permission Denial: opening provider " + cpi.name
6246                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6247                    + ", uid=" + callingUid + ") requires "
6248                    + cpi.readPermission + " or " + cpi.writePermission;
6249        }
6250        Slog.w(TAG, msg);
6251        return msg;
6252    }
6253
6254    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6255            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6256        if (r != null) {
6257            for (int i=0; i<r.conProviders.size(); i++) {
6258                ContentProviderConnection conn = r.conProviders.get(i);
6259                if (conn.provider == cpr) {
6260                    if (DEBUG_PROVIDER) Slog.v(TAG,
6261                            "Adding provider requested by "
6262                            + r.processName + " from process "
6263                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6264                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6265                    if (stable) {
6266                        conn.stableCount++;
6267                        conn.numStableIncs++;
6268                    } else {
6269                        conn.unstableCount++;
6270                        conn.numUnstableIncs++;
6271                    }
6272                    return conn;
6273                }
6274            }
6275            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6276            if (stable) {
6277                conn.stableCount = 1;
6278                conn.numStableIncs = 1;
6279            } else {
6280                conn.unstableCount = 1;
6281                conn.numUnstableIncs = 1;
6282            }
6283            cpr.connections.add(conn);
6284            r.conProviders.add(conn);
6285            return conn;
6286        }
6287        cpr.addExternalProcessHandleLocked(externalProcessToken);
6288        return null;
6289    }
6290
6291    boolean decProviderCountLocked(ContentProviderConnection conn,
6292            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6293        if (conn != null) {
6294            cpr = conn.provider;
6295            if (DEBUG_PROVIDER) Slog.v(TAG,
6296                    "Removing provider requested by "
6297                    + conn.client.processName + " from process "
6298                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6299                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6300            if (stable) {
6301                conn.stableCount--;
6302            } else {
6303                conn.unstableCount--;
6304            }
6305            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6306                cpr.connections.remove(conn);
6307                conn.client.conProviders.remove(conn);
6308                return true;
6309            }
6310            return false;
6311        }
6312        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6313        return false;
6314    }
6315
6316    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6317            String name, IBinder token, boolean stable, int userId) {
6318        ContentProviderRecord cpr;
6319        ContentProviderConnection conn = null;
6320        ProviderInfo cpi = null;
6321
6322        synchronized(this) {
6323            ProcessRecord r = null;
6324            if (caller != null) {
6325                r = getRecordForAppLocked(caller);
6326                if (r == null) {
6327                    throw new SecurityException(
6328                            "Unable to find app for caller " + caller
6329                          + " (pid=" + Binder.getCallingPid()
6330                          + ") when getting content provider " + name);
6331                }
6332                if (r.userId != userId) {
6333                    throw new SecurityException("Calling requested user " + userId
6334                            + " but app is user " + r.userId);
6335                }
6336            }
6337
6338            // First check if this content provider has been published...
6339            cpr = mProviderMap.getProviderByName(name, userId);
6340            boolean providerRunning = cpr != null;
6341            if (providerRunning) {
6342                cpi = cpr.info;
6343                String msg;
6344                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6345                    throw new SecurityException(msg);
6346                }
6347
6348                if (r != null && cpr.canRunHere(r)) {
6349                    // This provider has been published or is in the process
6350                    // of being published...  but it is also allowed to run
6351                    // in the caller's process, so don't make a connection
6352                    // and just let the caller instantiate its own instance.
6353                    ContentProviderHolder holder = cpr.newHolder(null);
6354                    // don't give caller the provider object, it needs
6355                    // to make its own.
6356                    holder.provider = null;
6357                    return holder;
6358                }
6359
6360                final long origId = Binder.clearCallingIdentity();
6361
6362                // In this case the provider instance already exists, so we can
6363                // return it right away.
6364                conn = incProviderCountLocked(r, cpr, token, stable);
6365                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6366                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6367                        // If this is a perceptible app accessing the provider,
6368                        // make sure to count it as being accessed and thus
6369                        // back up on the LRU list.  This is good because
6370                        // content providers are often expensive to start.
6371                        updateLruProcessLocked(cpr.proc, false, true);
6372                    }
6373                }
6374
6375                if (cpr.proc != null) {
6376                    if (false) {
6377                        if (cpr.name.flattenToShortString().equals(
6378                                "com.android.providers.calendar/.CalendarProvider2")) {
6379                            Slog.v(TAG, "****************** KILLING "
6380                                + cpr.name.flattenToShortString());
6381                            Process.killProcess(cpr.proc.pid);
6382                        }
6383                    }
6384                    boolean success = updateOomAdjLocked(cpr.proc);
6385                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6386                    // NOTE: there is still a race here where a signal could be
6387                    // pending on the process even though we managed to update its
6388                    // adj level.  Not sure what to do about this, but at least
6389                    // the race is now smaller.
6390                    if (!success) {
6391                        // Uh oh...  it looks like the provider's process
6392                        // has been killed on us.  We need to wait for a new
6393                        // process to be started, and make sure its death
6394                        // doesn't kill our process.
6395                        Slog.i(TAG,
6396                                "Existing provider " + cpr.name.flattenToShortString()
6397                                + " is crashing; detaching " + r);
6398                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6399                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6400                        if (!lastRef) {
6401                            // This wasn't the last ref our process had on
6402                            // the provider...  we have now been killed, bail.
6403                            return null;
6404                        }
6405                        providerRunning = false;
6406                        conn = null;
6407                    }
6408                }
6409
6410                Binder.restoreCallingIdentity(origId);
6411            }
6412
6413            boolean singleton;
6414            if (!providerRunning) {
6415                try {
6416                    cpi = AppGlobals.getPackageManager().
6417                        resolveContentProvider(name,
6418                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6419                } catch (RemoteException ex) {
6420                }
6421                if (cpi == null) {
6422                    return null;
6423                }
6424                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6425                        cpi.name, cpi.flags);
6426                if (singleton) {
6427                    userId = 0;
6428                }
6429                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6430
6431                String msg;
6432                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6433                    throw new SecurityException(msg);
6434                }
6435
6436                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6437                        && !cpi.processName.equals("system")) {
6438                    // If this content provider does not run in the system
6439                    // process, and the system is not yet ready to run other
6440                    // processes, then fail fast instead of hanging.
6441                    throw new IllegalArgumentException(
6442                            "Attempt to launch content provider before system ready");
6443                }
6444
6445                // Make sure that the user who owns this provider is started.  If not,
6446                // we don't want to allow it to run.
6447                if (mStartedUsers.get(userId) == null) {
6448                    Slog.w(TAG, "Unable to launch app "
6449                            + cpi.applicationInfo.packageName + "/"
6450                            + cpi.applicationInfo.uid + " for provider "
6451                            + name + ": user " + userId + " is stopped");
6452                    return null;
6453                }
6454
6455                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6456                cpr = mProviderMap.getProviderByClass(comp, userId);
6457                final boolean firstClass = cpr == null;
6458                if (firstClass) {
6459                    try {
6460                        ApplicationInfo ai =
6461                            AppGlobals.getPackageManager().
6462                                getApplicationInfo(
6463                                        cpi.applicationInfo.packageName,
6464                                        STOCK_PM_FLAGS, userId);
6465                        if (ai == null) {
6466                            Slog.w(TAG, "No package info for content provider "
6467                                    + cpi.name);
6468                            return null;
6469                        }
6470                        ai = getAppInfoForUser(ai, userId);
6471                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6472                    } catch (RemoteException ex) {
6473                        // pm is in same process, this will never happen.
6474                    }
6475                }
6476
6477                if (r != null && cpr.canRunHere(r)) {
6478                    // If this is a multiprocess provider, then just return its
6479                    // info and allow the caller to instantiate it.  Only do
6480                    // this if the provider is the same user as the caller's
6481                    // process, or can run as root (so can be in any process).
6482                    return cpr.newHolder(null);
6483                }
6484
6485                if (DEBUG_PROVIDER) {
6486                    RuntimeException e = new RuntimeException("here");
6487                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6488                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6489                }
6490
6491                // This is single process, and our app is now connecting to it.
6492                // See if we are already in the process of launching this
6493                // provider.
6494                final int N = mLaunchingProviders.size();
6495                int i;
6496                for (i=0; i<N; i++) {
6497                    if (mLaunchingProviders.get(i) == cpr) {
6498                        break;
6499                    }
6500                }
6501
6502                // If the provider is not already being launched, then get it
6503                // started.
6504                if (i >= N) {
6505                    final long origId = Binder.clearCallingIdentity();
6506
6507                    try {
6508                        // Content provider is now in use, its package can't be stopped.
6509                        try {
6510                            AppGlobals.getPackageManager().setPackageStoppedState(
6511                                    cpr.appInfo.packageName, false, userId);
6512                        } catch (RemoteException e) {
6513                        } catch (IllegalArgumentException e) {
6514                            Slog.w(TAG, "Failed trying to unstop package "
6515                                    + cpr.appInfo.packageName + ": " + e);
6516                        }
6517
6518                        ProcessRecord proc = startProcessLocked(cpi.processName,
6519                                cpr.appInfo, false, 0, "content provider",
6520                                new ComponentName(cpi.applicationInfo.packageName,
6521                                        cpi.name), false, false);
6522                        if (proc == null) {
6523                            Slog.w(TAG, "Unable to launch app "
6524                                    + cpi.applicationInfo.packageName + "/"
6525                                    + cpi.applicationInfo.uid + " for provider "
6526                                    + name + ": process is bad");
6527                            return null;
6528                        }
6529                        cpr.launchingApp = proc;
6530                        mLaunchingProviders.add(cpr);
6531                    } finally {
6532                        Binder.restoreCallingIdentity(origId);
6533                    }
6534                }
6535
6536                // Make sure the provider is published (the same provider class
6537                // may be published under multiple names).
6538                if (firstClass) {
6539                    mProviderMap.putProviderByClass(comp, cpr);
6540                }
6541
6542                mProviderMap.putProviderByName(name, cpr);
6543                conn = incProviderCountLocked(r, cpr, token, stable);
6544                if (conn != null) {
6545                    conn.waiting = true;
6546                }
6547            }
6548        }
6549
6550        // Wait for the provider to be published...
6551        synchronized (cpr) {
6552            while (cpr.provider == null) {
6553                if (cpr.launchingApp == null) {
6554                    Slog.w(TAG, "Unable to launch app "
6555                            + cpi.applicationInfo.packageName + "/"
6556                            + cpi.applicationInfo.uid + " for provider "
6557                            + name + ": launching app became null");
6558                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6559                            cpi.applicationInfo.packageName,
6560                            cpi.applicationInfo.uid, name);
6561                    return null;
6562                }
6563                try {
6564                    if (DEBUG_MU) {
6565                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6566                                + cpr.launchingApp);
6567                    }
6568                    if (conn != null) {
6569                        conn.waiting = true;
6570                    }
6571                    cpr.wait();
6572                } catch (InterruptedException ex) {
6573                } finally {
6574                    if (conn != null) {
6575                        conn.waiting = false;
6576                    }
6577                }
6578            }
6579        }
6580        return cpr != null ? cpr.newHolder(conn) : null;
6581    }
6582
6583    public final ContentProviderHolder getContentProvider(
6584            IApplicationThread caller, String name, boolean stable) {
6585        enforceNotIsolatedCaller("getContentProvider");
6586        if (caller == null) {
6587            String msg = "null IApplicationThread when getting content provider "
6588                    + name;
6589            Slog.w(TAG, msg);
6590            throw new SecurityException(msg);
6591        }
6592
6593        return getContentProviderImpl(caller, name, null, stable,
6594                UserHandle.getCallingUserId());
6595    }
6596
6597    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6598        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6599            "Do not have permission in call getContentProviderExternal()");
6600        return getContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6601    }
6602
6603    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6604            IBinder token, int userId) {
6605        return getContentProviderImpl(null, name, token, true, userId);
6606    }
6607
6608    /**
6609     * Drop a content provider from a ProcessRecord's bookkeeping
6610     * @param cpr
6611     */
6612    public void removeContentProvider(IBinder connection, boolean stable) {
6613        enforceNotIsolatedCaller("removeContentProvider");
6614        synchronized (this) {
6615            ContentProviderConnection conn;
6616            try {
6617                conn = (ContentProviderConnection)connection;
6618            } catch (ClassCastException e) {
6619                String msg ="removeContentProvider: " + connection
6620                        + " not a ContentProviderConnection";
6621                Slog.w(TAG, msg);
6622                throw new IllegalArgumentException(msg);
6623            }
6624            if (conn == null) {
6625                throw new NullPointerException("connection is null");
6626            }
6627            if (decProviderCountLocked(conn, null, null, stable)) {
6628                updateOomAdjLocked();
6629            }
6630        }
6631    }
6632
6633    public void removeContentProviderExternal(String name, IBinder token) {
6634        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6635            "Do not have permission in call removeContentProviderExternal()");
6636        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6637    }
6638
6639    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6640        synchronized (this) {
6641            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6642            if(cpr == null) {
6643                //remove from mProvidersByClass
6644                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6645                return;
6646            }
6647
6648            //update content provider record entry info
6649            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6650            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6651            if (localCpr.hasExternalProcessHandles()) {
6652                if (localCpr.removeExternalProcessHandleLocked(token)) {
6653                    updateOomAdjLocked();
6654                } else {
6655                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6656                            + " with no external reference for token: "
6657                            + token + ".");
6658                }
6659            } else {
6660                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6661                        + " with no external references.");
6662            }
6663        }
6664    }
6665
6666    public final void publishContentProviders(IApplicationThread caller,
6667            List<ContentProviderHolder> providers) {
6668        if (providers == null) {
6669            return;
6670        }
6671
6672        enforceNotIsolatedCaller("publishContentProviders");
6673        synchronized (this) {
6674            final ProcessRecord r = getRecordForAppLocked(caller);
6675            if (DEBUG_MU)
6676                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6677            if (r == null) {
6678                throw new SecurityException(
6679                        "Unable to find app for caller " + caller
6680                      + " (pid=" + Binder.getCallingPid()
6681                      + ") when publishing content providers");
6682            }
6683
6684            final long origId = Binder.clearCallingIdentity();
6685
6686            final int N = providers.size();
6687            for (int i=0; i<N; i++) {
6688                ContentProviderHolder src = providers.get(i);
6689                if (src == null || src.info == null || src.provider == null) {
6690                    continue;
6691                }
6692                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6693                if (DEBUG_MU)
6694                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6695                if (dst != null) {
6696                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6697                    mProviderMap.putProviderByClass(comp, dst);
6698                    String names[] = dst.info.authority.split(";");
6699                    for (int j = 0; j < names.length; j++) {
6700                        mProviderMap.putProviderByName(names[j], dst);
6701                    }
6702
6703                    int NL = mLaunchingProviders.size();
6704                    int j;
6705                    for (j=0; j<NL; j++) {
6706                        if (mLaunchingProviders.get(j) == dst) {
6707                            mLaunchingProviders.remove(j);
6708                            j--;
6709                            NL--;
6710                        }
6711                    }
6712                    synchronized (dst) {
6713                        dst.provider = src.provider;
6714                        dst.proc = r;
6715                        dst.notifyAll();
6716                    }
6717                    updateOomAdjLocked(r);
6718                }
6719            }
6720
6721            Binder.restoreCallingIdentity(origId);
6722        }
6723    }
6724
6725    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6726        ContentProviderConnection conn;
6727        try {
6728            conn = (ContentProviderConnection)connection;
6729        } catch (ClassCastException e) {
6730            String msg ="refContentProvider: " + connection
6731                    + " not a ContentProviderConnection";
6732            Slog.w(TAG, msg);
6733            throw new IllegalArgumentException(msg);
6734        }
6735        if (conn == null) {
6736            throw new NullPointerException("connection is null");
6737        }
6738
6739        synchronized (this) {
6740            if (stable > 0) {
6741                conn.numStableIncs += stable;
6742            }
6743            stable = conn.stableCount + stable;
6744            if (stable < 0) {
6745                throw new IllegalStateException("stableCount < 0: " + stable);
6746            }
6747
6748            if (unstable > 0) {
6749                conn.numUnstableIncs += unstable;
6750            }
6751            unstable = conn.unstableCount + unstable;
6752            if (unstable < 0) {
6753                throw new IllegalStateException("unstableCount < 0: " + unstable);
6754            }
6755
6756            if ((stable+unstable) <= 0) {
6757                throw new IllegalStateException("ref counts can't go to zero here: stable="
6758                        + stable + " unstable=" + unstable);
6759            }
6760            conn.stableCount = stable;
6761            conn.unstableCount = unstable;
6762            return !conn.dead;
6763        }
6764    }
6765
6766    public void unstableProviderDied(IBinder connection) {
6767        ContentProviderConnection conn;
6768        try {
6769            conn = (ContentProviderConnection)connection;
6770        } catch (ClassCastException e) {
6771            String msg ="refContentProvider: " + connection
6772                    + " not a ContentProviderConnection";
6773            Slog.w(TAG, msg);
6774            throw new IllegalArgumentException(msg);
6775        }
6776        if (conn == null) {
6777            throw new NullPointerException("connection is null");
6778        }
6779
6780        // Safely retrieve the content provider associated with the connection.
6781        IContentProvider provider;
6782        synchronized (this) {
6783            provider = conn.provider.provider;
6784        }
6785
6786        if (provider == null) {
6787            // Um, yeah, we're way ahead of you.
6788            return;
6789        }
6790
6791        // Make sure the caller is being honest with us.
6792        if (provider.asBinder().pingBinder()) {
6793            // Er, no, still looks good to us.
6794            synchronized (this) {
6795                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6796                        + " says " + conn + " died, but we don't agree");
6797                return;
6798            }
6799        }
6800
6801        // Well look at that!  It's dead!
6802        synchronized (this) {
6803            if (conn.provider.provider != provider) {
6804                // But something changed...  good enough.
6805                return;
6806            }
6807
6808            ProcessRecord proc = conn.provider.proc;
6809            if (proc == null || proc.thread == null) {
6810                // Seems like the process is already cleaned up.
6811                return;
6812            }
6813
6814            // As far as we're concerned, this is just like receiving a
6815            // death notification...  just a bit prematurely.
6816            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6817                    + ") early provider death");
6818            final long ident = Binder.clearCallingIdentity();
6819            try {
6820                appDiedLocked(proc, proc.pid, proc.thread);
6821            } finally {
6822                Binder.restoreCallingIdentity(ident);
6823            }
6824        }
6825    }
6826
6827    public static final void installSystemProviders() {
6828        List<ProviderInfo> providers;
6829        synchronized (mSelf) {
6830            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6831            providers = mSelf.generateApplicationProvidersLocked(app);
6832            if (providers != null) {
6833                for (int i=providers.size()-1; i>=0; i--) {
6834                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6835                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6836                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6837                                + ": not system .apk");
6838                        providers.remove(i);
6839                    }
6840                }
6841            }
6842        }
6843        if (providers != null) {
6844            mSystemThread.installSystemProviders(providers);
6845        }
6846
6847        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6848
6849        mSelf.mUsageStatsService.monitorPackages();
6850    }
6851
6852    /**
6853     * Allows app to retrieve the MIME type of a URI without having permission
6854     * to access its content provider.
6855     *
6856     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6857     *
6858     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6859     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6860     */
6861    public String getProviderMimeType(Uri uri, int userId) {
6862        enforceNotIsolatedCaller("getProviderMimeType");
6863        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
6864                userId, false, true, "getProviderMimeType", null);
6865        final String name = uri.getAuthority();
6866        final long ident = Binder.clearCallingIdentity();
6867        ContentProviderHolder holder = null;
6868
6869        try {
6870            holder = getContentProviderExternalUnchecked(name, null, userId);
6871            if (holder != null) {
6872                return holder.provider.getType(uri);
6873            }
6874        } catch (RemoteException e) {
6875            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6876            return null;
6877        } finally {
6878            if (holder != null) {
6879                removeContentProviderExternalUnchecked(name, null, userId);
6880            }
6881            Binder.restoreCallingIdentity(ident);
6882        }
6883
6884        return null;
6885    }
6886
6887    // =========================================================
6888    // GLOBAL MANAGEMENT
6889    // =========================================================
6890
6891    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6892            ApplicationInfo info, String customProcess, boolean isolated) {
6893        String proc = customProcess != null ? customProcess : info.processName;
6894        BatteryStatsImpl.Uid.Proc ps = null;
6895        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6896        int uid = info.uid;
6897        if (isolated) {
6898            int userId = UserHandle.getUserId(uid);
6899            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6900            uid = 0;
6901            while (true) {
6902                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6903                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6904                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6905                }
6906                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6907                mNextIsolatedProcessUid++;
6908                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6909                    // No process for this uid, use it.
6910                    break;
6911                }
6912                stepsLeft--;
6913                if (stepsLeft <= 0) {
6914                    return null;
6915                }
6916            }
6917        }
6918        synchronized (stats) {
6919            ps = stats.getProcessStatsLocked(info.uid, proc);
6920        }
6921        return new ProcessRecord(ps, thread, info, proc, uid);
6922    }
6923
6924    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6925        ProcessRecord app;
6926        if (!isolated) {
6927            app = getProcessRecordLocked(info.processName, info.uid);
6928        } else {
6929            app = null;
6930        }
6931
6932        if (app == null) {
6933            app = newProcessRecordLocked(null, info, null, isolated);
6934            mProcessNames.put(info.processName, app.uid, app);
6935            if (isolated) {
6936                mIsolatedProcesses.put(app.uid, app);
6937            }
6938            updateLruProcessLocked(app, true, true);
6939        }
6940
6941        // This package really, really can not be stopped.
6942        try {
6943            AppGlobals.getPackageManager().setPackageStoppedState(
6944                    info.packageName, false, UserHandle.getUserId(app.uid));
6945        } catch (RemoteException e) {
6946        } catch (IllegalArgumentException e) {
6947            Slog.w(TAG, "Failed trying to unstop package "
6948                    + info.packageName + ": " + e);
6949        }
6950
6951        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6952                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6953            app.persistent = true;
6954            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6955        }
6956        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6957            mPersistentStartingProcesses.add(app);
6958            startProcessLocked(app, "added application", app.processName);
6959        }
6960
6961        return app;
6962    }
6963
6964    public void unhandledBack() {
6965        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6966                "unhandledBack()");
6967
6968        synchronized(this) {
6969            int count = mMainStack.mHistory.size();
6970            if (DEBUG_SWITCH) Slog.d(
6971                TAG, "Performing unhandledBack(): stack size = " + count);
6972            if (count > 1) {
6973                final long origId = Binder.clearCallingIdentity();
6974                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6975                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6976                Binder.restoreCallingIdentity(origId);
6977            }
6978        }
6979    }
6980
6981    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6982        enforceNotIsolatedCaller("openContentUri");
6983        final int userId = UserHandle.getCallingUserId();
6984        String name = uri.getAuthority();
6985        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
6986        ParcelFileDescriptor pfd = null;
6987        if (cph != null) {
6988            // We record the binder invoker's uid in thread-local storage before
6989            // going to the content provider to open the file.  Later, in the code
6990            // that handles all permissions checks, we look for this uid and use
6991            // that rather than the Activity Manager's own uid.  The effect is that
6992            // we do the check against the caller's permissions even though it looks
6993            // to the content provider like the Activity Manager itself is making
6994            // the request.
6995            sCallerIdentity.set(new Identity(
6996                    Binder.getCallingPid(), Binder.getCallingUid()));
6997            try {
6998                pfd = cph.provider.openFile(uri, "r");
6999            } catch (FileNotFoundException e) {
7000                // do nothing; pfd will be returned null
7001            } finally {
7002                // Ensure that whatever happens, we clean up the identity state
7003                sCallerIdentity.remove();
7004            }
7005
7006            // We've got the fd now, so we're done with the provider.
7007            removeContentProviderExternalUnchecked(name, null, userId);
7008        } else {
7009            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
7010        }
7011        return pfd;
7012    }
7013
7014    // Actually is sleeping or shutting down or whatever else in the future
7015    // is an inactive state.
7016    public boolean isSleeping() {
7017        return mSleeping || mShuttingDown;
7018    }
7019
7020    public void goingToSleep() {
7021        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7022                != PackageManager.PERMISSION_GRANTED) {
7023            throw new SecurityException("Requires permission "
7024                    + android.Manifest.permission.DEVICE_POWER);
7025        }
7026
7027        synchronized(this) {
7028            mWentToSleep = true;
7029            updateEventDispatchingLocked();
7030
7031            if (!mSleeping) {
7032                mSleeping = true;
7033                mMainStack.stopIfSleepingLocked();
7034
7035                // Initialize the wake times of all processes.
7036                checkExcessivePowerUsageLocked(false);
7037                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7038                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7039                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7040            }
7041        }
7042    }
7043
7044    public boolean shutdown(int timeout) {
7045        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7046                != PackageManager.PERMISSION_GRANTED) {
7047            throw new SecurityException("Requires permission "
7048                    + android.Manifest.permission.SHUTDOWN);
7049        }
7050
7051        boolean timedout = false;
7052
7053        synchronized(this) {
7054            mShuttingDown = true;
7055            updateEventDispatchingLocked();
7056
7057            if (mMainStack.mResumedActivity != null) {
7058                mMainStack.stopIfSleepingLocked();
7059                final long endTime = System.currentTimeMillis() + timeout;
7060                while (mMainStack.mResumedActivity != null
7061                        || mMainStack.mPausingActivity != null) {
7062                    long delay = endTime - System.currentTimeMillis();
7063                    if (delay <= 0) {
7064                        Slog.w(TAG, "Activity manager shutdown timed out");
7065                        timedout = true;
7066                        break;
7067                    }
7068                    try {
7069                        this.wait();
7070                    } catch (InterruptedException e) {
7071                    }
7072                }
7073            }
7074        }
7075
7076        mUsageStatsService.shutdown();
7077        mBatteryStatsService.shutdown();
7078
7079        return timedout;
7080    }
7081
7082    public final void activitySlept(IBinder token) {
7083        if (localLOGV) Slog.v(
7084            TAG, "Activity slept: token=" + token);
7085
7086        ActivityRecord r = null;
7087
7088        final long origId = Binder.clearCallingIdentity();
7089
7090        synchronized (this) {
7091            r = mMainStack.isInStackLocked(token);
7092            if (r != null) {
7093                mMainStack.activitySleptLocked(r);
7094            }
7095        }
7096
7097        Binder.restoreCallingIdentity(origId);
7098    }
7099
7100    private void comeOutOfSleepIfNeededLocked() {
7101        if (!mWentToSleep && !mLockScreenShown) {
7102            if (mSleeping) {
7103                mSleeping = false;
7104                mMainStack.awakeFromSleepingLocked();
7105                mMainStack.resumeTopActivityLocked(null);
7106            }
7107        }
7108    }
7109
7110    public void wakingUp() {
7111        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7112                != PackageManager.PERMISSION_GRANTED) {
7113            throw new SecurityException("Requires permission "
7114                    + android.Manifest.permission.DEVICE_POWER);
7115        }
7116
7117        synchronized(this) {
7118            mWentToSleep = false;
7119            updateEventDispatchingLocked();
7120            comeOutOfSleepIfNeededLocked();
7121        }
7122    }
7123
7124    private void updateEventDispatchingLocked() {
7125        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7126    }
7127
7128    public void setLockScreenShown(boolean shown) {
7129        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7130                != PackageManager.PERMISSION_GRANTED) {
7131            throw new SecurityException("Requires permission "
7132                    + android.Manifest.permission.DEVICE_POWER);
7133        }
7134
7135        synchronized(this) {
7136            mLockScreenShown = shown;
7137            comeOutOfSleepIfNeededLocked();
7138        }
7139    }
7140
7141    public void stopAppSwitches() {
7142        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7143                != PackageManager.PERMISSION_GRANTED) {
7144            throw new SecurityException("Requires permission "
7145                    + android.Manifest.permission.STOP_APP_SWITCHES);
7146        }
7147
7148        synchronized(this) {
7149            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7150                    + APP_SWITCH_DELAY_TIME;
7151            mDidAppSwitch = false;
7152            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7153            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7154            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7155        }
7156    }
7157
7158    public void resumeAppSwitches() {
7159        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7160                != PackageManager.PERMISSION_GRANTED) {
7161            throw new SecurityException("Requires permission "
7162                    + android.Manifest.permission.STOP_APP_SWITCHES);
7163        }
7164
7165        synchronized(this) {
7166            // Note that we don't execute any pending app switches... we will
7167            // let those wait until either the timeout, or the next start
7168            // activity request.
7169            mAppSwitchesAllowedTime = 0;
7170        }
7171    }
7172
7173    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7174            String name) {
7175        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7176            return true;
7177        }
7178
7179        final int perm = checkComponentPermission(
7180                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7181                callingUid, -1, true);
7182        if (perm == PackageManager.PERMISSION_GRANTED) {
7183            return true;
7184        }
7185
7186        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7187        return false;
7188    }
7189
7190    public void setDebugApp(String packageName, boolean waitForDebugger,
7191            boolean persistent) {
7192        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7193                "setDebugApp()");
7194
7195        // Note that this is not really thread safe if there are multiple
7196        // callers into it at the same time, but that's not a situation we
7197        // care about.
7198        if (persistent) {
7199            final ContentResolver resolver = mContext.getContentResolver();
7200            Settings.System.putString(
7201                resolver, Settings.System.DEBUG_APP,
7202                packageName);
7203            Settings.System.putInt(
7204                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7205                waitForDebugger ? 1 : 0);
7206        }
7207
7208        synchronized (this) {
7209            if (!persistent) {
7210                mOrigDebugApp = mDebugApp;
7211                mOrigWaitForDebugger = mWaitForDebugger;
7212            }
7213            mDebugApp = packageName;
7214            mWaitForDebugger = waitForDebugger;
7215            mDebugTransient = !persistent;
7216            if (packageName != null) {
7217                final long origId = Binder.clearCallingIdentity();
7218                forceStopPackageLocked(packageName, -1, false, false, true, true,
7219                        UserHandle.USER_ALL);
7220                Binder.restoreCallingIdentity(origId);
7221            }
7222        }
7223    }
7224
7225    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7226        synchronized (this) {
7227            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7228            if (!isDebuggable) {
7229                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7230                    throw new SecurityException("Process not debuggable: " + app.packageName);
7231                }
7232            }
7233
7234            mOpenGlTraceApp = processName;
7235        }
7236    }
7237
7238    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7239            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7240        synchronized (this) {
7241            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7242            if (!isDebuggable) {
7243                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7244                    throw new SecurityException("Process not debuggable: " + app.packageName);
7245                }
7246            }
7247            mProfileApp = processName;
7248            mProfileFile = profileFile;
7249            if (mProfileFd != null) {
7250                try {
7251                    mProfileFd.close();
7252                } catch (IOException e) {
7253                }
7254                mProfileFd = null;
7255            }
7256            mProfileFd = profileFd;
7257            mProfileType = 0;
7258            mAutoStopProfiler = autoStopProfiler;
7259        }
7260    }
7261
7262    public void setAlwaysFinish(boolean enabled) {
7263        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7264                "setAlwaysFinish()");
7265
7266        Settings.System.putInt(
7267                mContext.getContentResolver(),
7268                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7269
7270        synchronized (this) {
7271            mAlwaysFinishActivities = enabled;
7272        }
7273    }
7274
7275    public void setActivityController(IActivityController controller) {
7276        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7277                "setActivityController()");
7278        synchronized (this) {
7279            mController = controller;
7280        }
7281    }
7282
7283    public boolean isUserAMonkey() {
7284        // For now the fact that there is a controller implies
7285        // we have a monkey.
7286        synchronized (this) {
7287            return mController != null;
7288        }
7289    }
7290
7291    public void registerProcessObserver(IProcessObserver observer) {
7292        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7293                "registerProcessObserver()");
7294        synchronized (this) {
7295            mProcessObservers.register(observer);
7296        }
7297    }
7298
7299    public void unregisterProcessObserver(IProcessObserver observer) {
7300        synchronized (this) {
7301            mProcessObservers.unregister(observer);
7302        }
7303    }
7304
7305    public void setImmersive(IBinder token, boolean immersive) {
7306        synchronized(this) {
7307            ActivityRecord r = mMainStack.isInStackLocked(token);
7308            if (r == null) {
7309                throw new IllegalArgumentException();
7310            }
7311            r.immersive = immersive;
7312        }
7313    }
7314
7315    public boolean isImmersive(IBinder token) {
7316        synchronized (this) {
7317            ActivityRecord r = mMainStack.isInStackLocked(token);
7318            if (r == null) {
7319                throw new IllegalArgumentException();
7320            }
7321            return r.immersive;
7322        }
7323    }
7324
7325    public boolean isTopActivityImmersive() {
7326        enforceNotIsolatedCaller("startActivity");
7327        synchronized (this) {
7328            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7329            return (r != null) ? r.immersive : false;
7330        }
7331    }
7332
7333    public final void enterSafeMode() {
7334        synchronized(this) {
7335            // It only makes sense to do this before the system is ready
7336            // and started launching other packages.
7337            if (!mSystemReady) {
7338                try {
7339                    AppGlobals.getPackageManager().enterSafeMode();
7340                } catch (RemoteException e) {
7341                }
7342            }
7343        }
7344    }
7345
7346    public final void showSafeModeOverlay() {
7347        View v = LayoutInflater.from(mContext).inflate(
7348                com.android.internal.R.layout.safe_mode, null);
7349        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7350        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7351        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7352        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7353        lp.gravity = Gravity.BOTTOM | Gravity.START;
7354        lp.format = v.getBackground().getOpacity();
7355        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7356                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7357        ((WindowManager)mContext.getSystemService(
7358                Context.WINDOW_SERVICE)).addView(v, lp);
7359    }
7360
7361    public void noteWakeupAlarm(IIntentSender sender) {
7362        if (!(sender instanceof PendingIntentRecord)) {
7363            return;
7364        }
7365        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7366        synchronized (stats) {
7367            if (mBatteryStatsService.isOnBattery()) {
7368                mBatteryStatsService.enforceCallingPermission();
7369                PendingIntentRecord rec = (PendingIntentRecord)sender;
7370                int MY_UID = Binder.getCallingUid();
7371                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7372                BatteryStatsImpl.Uid.Pkg pkg =
7373                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7374                pkg.incWakeupsLocked();
7375            }
7376        }
7377    }
7378
7379    public boolean killPids(int[] pids, String pReason, boolean secure) {
7380        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7381            throw new SecurityException("killPids only available to the system");
7382        }
7383        String reason = (pReason == null) ? "Unknown" : pReason;
7384        // XXX Note: don't acquire main activity lock here, because the window
7385        // manager calls in with its locks held.
7386
7387        boolean killed = false;
7388        synchronized (mPidsSelfLocked) {
7389            int[] types = new int[pids.length];
7390            int worstType = 0;
7391            for (int i=0; i<pids.length; i++) {
7392                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7393                if (proc != null) {
7394                    int type = proc.setAdj;
7395                    types[i] = type;
7396                    if (type > worstType) {
7397                        worstType = type;
7398                    }
7399                }
7400            }
7401
7402            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7403            // then constrain it so we will kill all hidden procs.
7404            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7405                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7406                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7407            }
7408
7409            // If this is not a secure call, don't let it kill processes that
7410            // are important.
7411            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7412                worstType = ProcessList.SERVICE_ADJ;
7413            }
7414
7415            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7416            for (int i=0; i<pids.length; i++) {
7417                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7418                if (proc == null) {
7419                    continue;
7420                }
7421                int adj = proc.setAdj;
7422                if (adj >= worstType && !proc.killedBackground) {
7423                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7424                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7425                            proc.processName, adj, reason);
7426                    killed = true;
7427                    proc.killedBackground = true;
7428                    Process.killProcessQuiet(pids[i]);
7429                }
7430            }
7431        }
7432        return killed;
7433    }
7434
7435    @Override
7436    public boolean killProcessesBelowForeground(String reason) {
7437        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7438            throw new SecurityException("killProcessesBelowForeground() only available to system");
7439        }
7440
7441        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7442    }
7443
7444    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7445        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7446            throw new SecurityException("killProcessesBelowAdj() only available to system");
7447        }
7448
7449        boolean killed = false;
7450        synchronized (mPidsSelfLocked) {
7451            final int size = mPidsSelfLocked.size();
7452            for (int i = 0; i < size; i++) {
7453                final int pid = mPidsSelfLocked.keyAt(i);
7454                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7455                if (proc == null) continue;
7456
7457                final int adj = proc.setAdj;
7458                if (adj > belowAdj && !proc.killedBackground) {
7459                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7460                    EventLog.writeEvent(
7461                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7462                    killed = true;
7463                    proc.killedBackground = true;
7464                    Process.killProcessQuiet(pid);
7465                }
7466            }
7467        }
7468        return killed;
7469    }
7470
7471    public final void startRunning(String pkg, String cls, String action,
7472            String data) {
7473        synchronized(this) {
7474            if (mStartRunning) {
7475                return;
7476            }
7477            mStartRunning = true;
7478            mTopComponent = pkg != null && cls != null
7479                    ? new ComponentName(pkg, cls) : null;
7480            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7481            mTopData = data;
7482            if (!mSystemReady) {
7483                return;
7484            }
7485        }
7486
7487        systemReady(null);
7488    }
7489
7490    private void retrieveSettings() {
7491        final ContentResolver resolver = mContext.getContentResolver();
7492        String debugApp = Settings.System.getString(
7493            resolver, Settings.System.DEBUG_APP);
7494        boolean waitForDebugger = Settings.System.getInt(
7495            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7496        boolean alwaysFinishActivities = Settings.System.getInt(
7497            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7498
7499        Configuration configuration = new Configuration();
7500        Settings.System.getConfiguration(resolver, configuration);
7501
7502        synchronized (this) {
7503            mDebugApp = mOrigDebugApp = debugApp;
7504            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7505            mAlwaysFinishActivities = alwaysFinishActivities;
7506            // This happens before any activities are started, so we can
7507            // change mConfiguration in-place.
7508            updateConfigurationLocked(configuration, null, false, true);
7509            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7510        }
7511    }
7512
7513    public boolean testIsSystemReady() {
7514        // no need to synchronize(this) just to read & return the value
7515        return mSystemReady;
7516    }
7517
7518    private static File getCalledPreBootReceiversFile() {
7519        File dataDir = Environment.getDataDirectory();
7520        File systemDir = new File(dataDir, "system");
7521        File fname = new File(systemDir, "called_pre_boots.dat");
7522        return fname;
7523    }
7524
7525    static final int LAST_DONE_VERSION = 10000;
7526
7527    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7528        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7529        File file = getCalledPreBootReceiversFile();
7530        FileInputStream fis = null;
7531        try {
7532            fis = new FileInputStream(file);
7533            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7534            int fvers = dis.readInt();
7535            if (fvers == LAST_DONE_VERSION) {
7536                String vers = dis.readUTF();
7537                String codename = dis.readUTF();
7538                String build = dis.readUTF();
7539                if (android.os.Build.VERSION.RELEASE.equals(vers)
7540                        && android.os.Build.VERSION.CODENAME.equals(codename)
7541                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7542                    int num = dis.readInt();
7543                    while (num > 0) {
7544                        num--;
7545                        String pkg = dis.readUTF();
7546                        String cls = dis.readUTF();
7547                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7548                    }
7549                }
7550            }
7551        } catch (FileNotFoundException e) {
7552        } catch (IOException e) {
7553            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7554        } finally {
7555            if (fis != null) {
7556                try {
7557                    fis.close();
7558                } catch (IOException e) {
7559                }
7560            }
7561        }
7562        return lastDoneReceivers;
7563    }
7564
7565    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7566        File file = getCalledPreBootReceiversFile();
7567        FileOutputStream fos = null;
7568        DataOutputStream dos = null;
7569        try {
7570            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7571            fos = new FileOutputStream(file);
7572            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7573            dos.writeInt(LAST_DONE_VERSION);
7574            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7575            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7576            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7577            dos.writeInt(list.size());
7578            for (int i=0; i<list.size(); i++) {
7579                dos.writeUTF(list.get(i).getPackageName());
7580                dos.writeUTF(list.get(i).getClassName());
7581            }
7582        } catch (IOException e) {
7583            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7584            file.delete();
7585        } finally {
7586            FileUtils.sync(fos);
7587            if (dos != null) {
7588                try {
7589                    dos.close();
7590                } catch (IOException e) {
7591                    // TODO Auto-generated catch block
7592                    e.printStackTrace();
7593                }
7594            }
7595        }
7596    }
7597
7598    public void systemReady(final Runnable goingCallback) {
7599        synchronized(this) {
7600            if (mSystemReady) {
7601                if (goingCallback != null) goingCallback.run();
7602                return;
7603            }
7604
7605            // Check to see if there are any update receivers to run.
7606            if (!mDidUpdate) {
7607                if (mWaitingUpdate) {
7608                    return;
7609                }
7610                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7611                List<ResolveInfo> ris = null;
7612                try {
7613                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7614                            intent, null, 0, 0);
7615                } catch (RemoteException e) {
7616                }
7617                if (ris != null) {
7618                    for (int i=ris.size()-1; i>=0; i--) {
7619                        if ((ris.get(i).activityInfo.applicationInfo.flags
7620                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7621                            ris.remove(i);
7622                        }
7623                    }
7624                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7625
7626                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7627
7628                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7629                    for (int i=0; i<ris.size(); i++) {
7630                        ActivityInfo ai = ris.get(i).activityInfo;
7631                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7632                        if (lastDoneReceivers.contains(comp)) {
7633                            ris.remove(i);
7634                            i--;
7635                        }
7636                    }
7637
7638                    for (int i=0; i<ris.size(); i++) {
7639                        ActivityInfo ai = ris.get(i).activityInfo;
7640                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7641                        doneReceivers.add(comp);
7642                        intent.setComponent(comp);
7643                        IIntentReceiver finisher = null;
7644                        if (i == ris.size()-1) {
7645                            finisher = new IIntentReceiver.Stub() {
7646                                public void performReceive(Intent intent, int resultCode,
7647                                        String data, Bundle extras, boolean ordered,
7648                                        boolean sticky, int sendingUser) {
7649                                    // The raw IIntentReceiver interface is called
7650                                    // with the AM lock held, so redispatch to
7651                                    // execute our code without the lock.
7652                                    mHandler.post(new Runnable() {
7653                                        public void run() {
7654                                            synchronized (ActivityManagerService.this) {
7655                                                mDidUpdate = true;
7656                                            }
7657                                            writeLastDonePreBootReceivers(doneReceivers);
7658                                            showBootMessage(mContext.getText(
7659                                                    R.string.android_upgrading_complete),
7660                                                    false);
7661                                            systemReady(goingCallback);
7662                                        }
7663                                    });
7664                                }
7665                            };
7666                        }
7667                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7668                        // XXX also need to send this to stopped users(!!!)
7669                        broadcastIntentLocked(null, null, intent, null, finisher,
7670                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7671                                UserHandle.USER_ALL);
7672                        if (finisher != null) {
7673                            mWaitingUpdate = true;
7674                        }
7675                    }
7676                }
7677                if (mWaitingUpdate) {
7678                    return;
7679                }
7680                mDidUpdate = true;
7681            }
7682
7683            mSystemReady = true;
7684            if (!mStartRunning) {
7685                return;
7686            }
7687        }
7688
7689        ArrayList<ProcessRecord> procsToKill = null;
7690        synchronized(mPidsSelfLocked) {
7691            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7692                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7693                if (!isAllowedWhileBooting(proc.info)){
7694                    if (procsToKill == null) {
7695                        procsToKill = new ArrayList<ProcessRecord>();
7696                    }
7697                    procsToKill.add(proc);
7698                }
7699            }
7700        }
7701
7702        synchronized(this) {
7703            if (procsToKill != null) {
7704                for (int i=procsToKill.size()-1; i>=0; i--) {
7705                    ProcessRecord proc = procsToKill.get(i);
7706                    Slog.i(TAG, "Removing system update proc: " + proc);
7707                    removeProcessLocked(proc, true, false, "system update done");
7708                }
7709            }
7710
7711            // Now that we have cleaned up any update processes, we
7712            // are ready to start launching real processes and know that
7713            // we won't trample on them any more.
7714            mProcessesReady = true;
7715        }
7716
7717        Slog.i(TAG, "System now ready");
7718        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7719            SystemClock.uptimeMillis());
7720
7721        synchronized(this) {
7722            // Make sure we have no pre-ready processes sitting around.
7723
7724            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7725                ResolveInfo ri = mContext.getPackageManager()
7726                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7727                                STOCK_PM_FLAGS);
7728                CharSequence errorMsg = null;
7729                if (ri != null) {
7730                    ActivityInfo ai = ri.activityInfo;
7731                    ApplicationInfo app = ai.applicationInfo;
7732                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7733                        mTopAction = Intent.ACTION_FACTORY_TEST;
7734                        mTopData = null;
7735                        mTopComponent = new ComponentName(app.packageName,
7736                                ai.name);
7737                    } else {
7738                        errorMsg = mContext.getResources().getText(
7739                                com.android.internal.R.string.factorytest_not_system);
7740                    }
7741                } else {
7742                    errorMsg = mContext.getResources().getText(
7743                            com.android.internal.R.string.factorytest_no_action);
7744                }
7745                if (errorMsg != null) {
7746                    mTopAction = null;
7747                    mTopData = null;
7748                    mTopComponent = null;
7749                    Message msg = Message.obtain();
7750                    msg.what = SHOW_FACTORY_ERROR_MSG;
7751                    msg.getData().putCharSequence("msg", errorMsg);
7752                    mHandler.sendMessage(msg);
7753                }
7754            }
7755        }
7756
7757        retrieveSettings();
7758
7759        if (goingCallback != null) goingCallback.run();
7760
7761        synchronized (this) {
7762            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7763                try {
7764                    List apps = AppGlobals.getPackageManager().
7765                        getPersistentApplications(STOCK_PM_FLAGS);
7766                    if (apps != null) {
7767                        int N = apps.size();
7768                        int i;
7769                        for (i=0; i<N; i++) {
7770                            ApplicationInfo info
7771                                = (ApplicationInfo)apps.get(i);
7772                            if (info != null &&
7773                                    !info.packageName.equals("android")) {
7774                                addAppLocked(info, false);
7775                            }
7776                        }
7777                    }
7778                } catch (RemoteException ex) {
7779                    // pm is in same process, this will never happen.
7780                }
7781            }
7782
7783            // Start up initial activity.
7784            mBooting = true;
7785
7786            try {
7787                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7788                    Message msg = Message.obtain();
7789                    msg.what = SHOW_UID_ERROR_MSG;
7790                    mHandler.sendMessage(msg);
7791                }
7792            } catch (RemoteException e) {
7793            }
7794
7795            mMainStack.resumeTopActivityLocked(null);
7796        }
7797    }
7798
7799    private boolean makeAppCrashingLocked(ProcessRecord app,
7800            String shortMsg, String longMsg, String stackTrace) {
7801        app.crashing = true;
7802        app.crashingReport = generateProcessError(app,
7803                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7804        startAppProblemLocked(app);
7805        app.stopFreezingAllLocked();
7806        return handleAppCrashLocked(app);
7807    }
7808
7809    private void makeAppNotRespondingLocked(ProcessRecord app,
7810            String activity, String shortMsg, String longMsg) {
7811        app.notResponding = true;
7812        app.notRespondingReport = generateProcessError(app,
7813                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7814                activity, shortMsg, longMsg, null);
7815        startAppProblemLocked(app);
7816        app.stopFreezingAllLocked();
7817    }
7818
7819    /**
7820     * Generate a process error record, suitable for attachment to a ProcessRecord.
7821     *
7822     * @param app The ProcessRecord in which the error occurred.
7823     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7824     *                      ActivityManager.AppErrorStateInfo
7825     * @param activity The activity associated with the crash, if known.
7826     * @param shortMsg Short message describing the crash.
7827     * @param longMsg Long message describing the crash.
7828     * @param stackTrace Full crash stack trace, may be null.
7829     *
7830     * @return Returns a fully-formed AppErrorStateInfo record.
7831     */
7832    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7833            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7834        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7835
7836        report.condition = condition;
7837        report.processName = app.processName;
7838        report.pid = app.pid;
7839        report.uid = app.info.uid;
7840        report.tag = activity;
7841        report.shortMsg = shortMsg;
7842        report.longMsg = longMsg;
7843        report.stackTrace = stackTrace;
7844
7845        return report;
7846    }
7847
7848    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7849        synchronized (this) {
7850            app.crashing = false;
7851            app.crashingReport = null;
7852            app.notResponding = false;
7853            app.notRespondingReport = null;
7854            if (app.anrDialog == fromDialog) {
7855                app.anrDialog = null;
7856            }
7857            if (app.waitDialog == fromDialog) {
7858                app.waitDialog = null;
7859            }
7860            if (app.pid > 0 && app.pid != MY_PID) {
7861                handleAppCrashLocked(app);
7862                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7863                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7864                        app.processName, app.setAdj, "user's request after error");
7865                Process.killProcessQuiet(app.pid);
7866            }
7867        }
7868    }
7869
7870    private boolean handleAppCrashLocked(ProcessRecord app) {
7871        if (mHeadless) {
7872            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7873            return false;
7874        }
7875        long now = SystemClock.uptimeMillis();
7876
7877        Long crashTime;
7878        if (!app.isolated) {
7879            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7880        } else {
7881            crashTime = null;
7882        }
7883        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7884            // This process loses!
7885            Slog.w(TAG, "Process " + app.info.processName
7886                    + " has crashed too many times: killing!");
7887            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7888                    app.info.processName, app.uid);
7889            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7890                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7891                if (r.app == app) {
7892                    Slog.w(TAG, "  Force finishing activity "
7893                        + r.intent.getComponent().flattenToShortString());
7894                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7895                }
7896            }
7897            if (!app.persistent) {
7898                // We don't want to start this process again until the user
7899                // explicitly does so...  but for persistent process, we really
7900                // need to keep it running.  If a persistent process is actually
7901                // repeatedly crashing, then badness for everyone.
7902                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7903                        app.info.processName);
7904                if (!app.isolated) {
7905                    // XXX We don't have a way to mark isolated processes
7906                    // as bad, since they don't have a peristent identity.
7907                    mBadProcesses.put(app.info.processName, app.uid, now);
7908                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7909                }
7910                app.bad = true;
7911                app.removed = true;
7912                // Don't let services in this process be restarted and potentially
7913                // annoy the user repeatedly.  Unless it is persistent, since those
7914                // processes run critical code.
7915                removeProcessLocked(app, false, false, "crash");
7916                mMainStack.resumeTopActivityLocked(null);
7917                return false;
7918            }
7919            mMainStack.resumeTopActivityLocked(null);
7920        } else {
7921            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7922            if (r != null && r.app == app) {
7923                // If the top running activity is from this crashing
7924                // process, then terminate it to avoid getting in a loop.
7925                Slog.w(TAG, "  Force finishing activity "
7926                        + r.intent.getComponent().flattenToShortString());
7927                int index = mMainStack.indexOfActivityLocked(r);
7928                r.stack.finishActivityLocked(r, index,
7929                        Activity.RESULT_CANCELED, null, "crashed");
7930                // Also terminate any activities below it that aren't yet
7931                // stopped, to avoid a situation where one will get
7932                // re-start our crashing activity once it gets resumed again.
7933                index--;
7934                if (index >= 0) {
7935                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7936                    if (r.state == ActivityState.RESUMED
7937                            || r.state == ActivityState.PAUSING
7938                            || r.state == ActivityState.PAUSED) {
7939                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7940                            Slog.w(TAG, "  Force finishing activity "
7941                                    + r.intent.getComponent().flattenToShortString());
7942                            r.stack.finishActivityLocked(r, index,
7943                                    Activity.RESULT_CANCELED, null, "crashed");
7944                        }
7945                    }
7946                }
7947            }
7948        }
7949
7950        // Bump up the crash count of any services currently running in the proc.
7951        if (app.services.size() != 0) {
7952            // Any services running in the application need to be placed
7953            // back in the pending list.
7954            Iterator<ServiceRecord> it = app.services.iterator();
7955            while (it.hasNext()) {
7956                ServiceRecord sr = it.next();
7957                sr.crashCount++;
7958            }
7959        }
7960
7961        // If the crashing process is what we consider to be the "home process" and it has been
7962        // replaced by a third-party app, clear the package preferred activities from packages
7963        // with a home activity running in the process to prevent a repeatedly crashing app
7964        // from blocking the user to manually clear the list.
7965        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7966                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7967            Iterator it = mHomeProcess.activities.iterator();
7968            while (it.hasNext()) {
7969                ActivityRecord r = (ActivityRecord)it.next();
7970                if (r.isHomeActivity) {
7971                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7972                    try {
7973                        ActivityThread.getPackageManager()
7974                                .clearPackagePreferredActivities(r.packageName);
7975                    } catch (RemoteException c) {
7976                        // pm is in same process, this will never happen.
7977                    }
7978                }
7979            }
7980        }
7981
7982        if (!app.isolated) {
7983            // XXX Can't keep track of crash times for isolated processes,
7984            // because they don't have a perisistent identity.
7985            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7986        }
7987
7988        return true;
7989    }
7990
7991    void startAppProblemLocked(ProcessRecord app) {
7992        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7993                mContext, app.info.packageName, app.info.flags);
7994        skipCurrentReceiverLocked(app);
7995    }
7996
7997    void skipCurrentReceiverLocked(ProcessRecord app) {
7998        for (BroadcastQueue queue : mBroadcastQueues) {
7999            queue.skipCurrentReceiverLocked(app);
8000        }
8001    }
8002
8003    /**
8004     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8005     * The application process will exit immediately after this call returns.
8006     * @param app object of the crashing app, null for the system server
8007     * @param crashInfo describing the exception
8008     */
8009    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8010        ProcessRecord r = findAppProcess(app, "Crash");
8011        final String processName = app == null ? "system_server"
8012                : (r == null ? "unknown" : r.processName);
8013
8014        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8015                processName,
8016                r == null ? -1 : r.info.flags,
8017                crashInfo.exceptionClassName,
8018                crashInfo.exceptionMessage,
8019                crashInfo.throwFileName,
8020                crashInfo.throwLineNumber);
8021
8022        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
8023
8024        crashApplication(r, crashInfo);
8025    }
8026
8027    public void handleApplicationStrictModeViolation(
8028            IBinder app,
8029            int violationMask,
8030            StrictMode.ViolationInfo info) {
8031        ProcessRecord r = findAppProcess(app, "StrictMode");
8032        if (r == null) {
8033            return;
8034        }
8035
8036        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
8037            Integer stackFingerprint = info.hashCode();
8038            boolean logIt = true;
8039            synchronized (mAlreadyLoggedViolatedStacks) {
8040                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8041                    logIt = false;
8042                    // TODO: sub-sample into EventLog for these, with
8043                    // the info.durationMillis?  Then we'd get
8044                    // the relative pain numbers, without logging all
8045                    // the stack traces repeatedly.  We'd want to do
8046                    // likewise in the client code, which also does
8047                    // dup suppression, before the Binder call.
8048                } else {
8049                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8050                        mAlreadyLoggedViolatedStacks.clear();
8051                    }
8052                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8053                }
8054            }
8055            if (logIt) {
8056                logStrictModeViolationToDropBox(r, info);
8057            }
8058        }
8059
8060        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8061            AppErrorResult result = new AppErrorResult();
8062            synchronized (this) {
8063                final long origId = Binder.clearCallingIdentity();
8064
8065                Message msg = Message.obtain();
8066                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8067                HashMap<String, Object> data = new HashMap<String, Object>();
8068                data.put("result", result);
8069                data.put("app", r);
8070                data.put("violationMask", violationMask);
8071                data.put("info", info);
8072                msg.obj = data;
8073                mHandler.sendMessage(msg);
8074
8075                Binder.restoreCallingIdentity(origId);
8076            }
8077            int res = result.get();
8078            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8079        }
8080    }
8081
8082    // Depending on the policy in effect, there could be a bunch of
8083    // these in quick succession so we try to batch these together to
8084    // minimize disk writes, number of dropbox entries, and maximize
8085    // compression, by having more fewer, larger records.
8086    private void logStrictModeViolationToDropBox(
8087            ProcessRecord process,
8088            StrictMode.ViolationInfo info) {
8089        if (info == null) {
8090            return;
8091        }
8092        final boolean isSystemApp = process == null ||
8093                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8094                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8095        final String processName = process == null ? "unknown" : process.processName;
8096        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8097        final DropBoxManager dbox = (DropBoxManager)
8098                mContext.getSystemService(Context.DROPBOX_SERVICE);
8099
8100        // Exit early if the dropbox isn't configured to accept this report type.
8101        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8102
8103        boolean bufferWasEmpty;
8104        boolean needsFlush;
8105        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8106        synchronized (sb) {
8107            bufferWasEmpty = sb.length() == 0;
8108            appendDropBoxProcessHeaders(process, processName, sb);
8109            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8110            sb.append("System-App: ").append(isSystemApp).append("\n");
8111            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8112            if (info.violationNumThisLoop != 0) {
8113                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8114            }
8115            if (info.numAnimationsRunning != 0) {
8116                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8117            }
8118            if (info.broadcastIntentAction != null) {
8119                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8120            }
8121            if (info.durationMillis != -1) {
8122                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8123            }
8124            if (info.numInstances != -1) {
8125                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8126            }
8127            if (info.tags != null) {
8128                for (String tag : info.tags) {
8129                    sb.append("Span-Tag: ").append(tag).append("\n");
8130                }
8131            }
8132            sb.append("\n");
8133            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8134                sb.append(info.crashInfo.stackTrace);
8135            }
8136            sb.append("\n");
8137
8138            // Only buffer up to ~64k.  Various logging bits truncate
8139            // things at 128k.
8140            needsFlush = (sb.length() > 64 * 1024);
8141        }
8142
8143        // Flush immediately if the buffer's grown too large, or this
8144        // is a non-system app.  Non-system apps are isolated with a
8145        // different tag & policy and not batched.
8146        //
8147        // Batching is useful during internal testing with
8148        // StrictMode settings turned up high.  Without batching,
8149        // thousands of separate files could be created on boot.
8150        if (!isSystemApp || needsFlush) {
8151            new Thread("Error dump: " + dropboxTag) {
8152                @Override
8153                public void run() {
8154                    String report;
8155                    synchronized (sb) {
8156                        report = sb.toString();
8157                        sb.delete(0, sb.length());
8158                        sb.trimToSize();
8159                    }
8160                    if (report.length() != 0) {
8161                        dbox.addText(dropboxTag, report);
8162                    }
8163                }
8164            }.start();
8165            return;
8166        }
8167
8168        // System app batching:
8169        if (!bufferWasEmpty) {
8170            // An existing dropbox-writing thread is outstanding, so
8171            // we don't need to start it up.  The existing thread will
8172            // catch the buffer appends we just did.
8173            return;
8174        }
8175
8176        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8177        // (After this point, we shouldn't access AMS internal data structures.)
8178        new Thread("Error dump: " + dropboxTag) {
8179            @Override
8180            public void run() {
8181                // 5 second sleep to let stacks arrive and be batched together
8182                try {
8183                    Thread.sleep(5000);  // 5 seconds
8184                } catch (InterruptedException e) {}
8185
8186                String errorReport;
8187                synchronized (mStrictModeBuffer) {
8188                    errorReport = mStrictModeBuffer.toString();
8189                    if (errorReport.length() == 0) {
8190                        return;
8191                    }
8192                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8193                    mStrictModeBuffer.trimToSize();
8194                }
8195                dbox.addText(dropboxTag, errorReport);
8196            }
8197        }.start();
8198    }
8199
8200    /**
8201     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8202     * @param app object of the crashing app, null for the system server
8203     * @param tag reported by the caller
8204     * @param crashInfo describing the context of the error
8205     * @return true if the process should exit immediately (WTF is fatal)
8206     */
8207    public boolean handleApplicationWtf(IBinder app, String tag,
8208            ApplicationErrorReport.CrashInfo crashInfo) {
8209        ProcessRecord r = findAppProcess(app, "WTF");
8210        final String processName = app == null ? "system_server"
8211                : (r == null ? "unknown" : r.processName);
8212
8213        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8214                processName,
8215                r == null ? -1 : r.info.flags,
8216                tag, crashInfo.exceptionMessage);
8217
8218        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8219
8220        if (r != null && r.pid != Process.myPid() &&
8221                Settings.Secure.getInt(mContext.getContentResolver(),
8222                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8223            crashApplication(r, crashInfo);
8224            return true;
8225        } else {
8226            return false;
8227        }
8228    }
8229
8230    /**
8231     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8232     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8233     */
8234    private ProcessRecord findAppProcess(IBinder app, String reason) {
8235        if (app == null) {
8236            return null;
8237        }
8238
8239        synchronized (this) {
8240            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8241                final int NA = apps.size();
8242                for (int ia=0; ia<NA; ia++) {
8243                    ProcessRecord p = apps.valueAt(ia);
8244                    if (p.thread != null && p.thread.asBinder() == app) {
8245                        return p;
8246                    }
8247                }
8248            }
8249
8250            Slog.w(TAG, "Can't find mystery application for " + reason
8251                    + " from pid=" + Binder.getCallingPid()
8252                    + " uid=" + Binder.getCallingUid() + ": " + app);
8253            return null;
8254        }
8255    }
8256
8257    /**
8258     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8259     * to append various headers to the dropbox log text.
8260     */
8261    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8262            StringBuilder sb) {
8263        // Watchdog thread ends up invoking this function (with
8264        // a null ProcessRecord) to add the stack file to dropbox.
8265        // Do not acquire a lock on this (am) in such cases, as it
8266        // could cause a potential deadlock, if and when watchdog
8267        // is invoked due to unavailability of lock on am and it
8268        // would prevent watchdog from killing system_server.
8269        if (process == null) {
8270            sb.append("Process: ").append(processName).append("\n");
8271            return;
8272        }
8273        // Note: ProcessRecord 'process' is guarded by the service
8274        // instance.  (notably process.pkgList, which could otherwise change
8275        // concurrently during execution of this method)
8276        synchronized (this) {
8277            sb.append("Process: ").append(processName).append("\n");
8278            int flags = process.info.flags;
8279            IPackageManager pm = AppGlobals.getPackageManager();
8280            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8281            for (String pkg : process.pkgList) {
8282                sb.append("Package: ").append(pkg);
8283                try {
8284                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8285                    if (pi != null) {
8286                        sb.append(" v").append(pi.versionCode);
8287                        if (pi.versionName != null) {
8288                            sb.append(" (").append(pi.versionName).append(")");
8289                        }
8290                    }
8291                } catch (RemoteException e) {
8292                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8293                }
8294                sb.append("\n");
8295            }
8296        }
8297    }
8298
8299    private static String processClass(ProcessRecord process) {
8300        if (process == null || process.pid == MY_PID) {
8301            return "system_server";
8302        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8303            return "system_app";
8304        } else {
8305            return "data_app";
8306        }
8307    }
8308
8309    /**
8310     * Write a description of an error (crash, WTF, ANR) to the drop box.
8311     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8312     * @param process which caused the error, null means the system server
8313     * @param activity which triggered the error, null if unknown
8314     * @param parent activity related to the error, null if unknown
8315     * @param subject line related to the error, null if absent
8316     * @param report in long form describing the error, null if absent
8317     * @param logFile to include in the report, null if none
8318     * @param crashInfo giving an application stack trace, null if absent
8319     */
8320    public void addErrorToDropBox(String eventType,
8321            ProcessRecord process, String processName, ActivityRecord activity,
8322            ActivityRecord parent, String subject,
8323            final String report, final File logFile,
8324            final ApplicationErrorReport.CrashInfo crashInfo) {
8325        // NOTE -- this must never acquire the ActivityManagerService lock,
8326        // otherwise the watchdog may be prevented from resetting the system.
8327
8328        final String dropboxTag = processClass(process) + "_" + eventType;
8329        final DropBoxManager dbox = (DropBoxManager)
8330                mContext.getSystemService(Context.DROPBOX_SERVICE);
8331
8332        // Exit early if the dropbox isn't configured to accept this report type.
8333        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8334
8335        final StringBuilder sb = new StringBuilder(1024);
8336        appendDropBoxProcessHeaders(process, processName, sb);
8337        if (activity != null) {
8338            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8339        }
8340        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8341            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8342        }
8343        if (parent != null && parent != activity) {
8344            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8345        }
8346        if (subject != null) {
8347            sb.append("Subject: ").append(subject).append("\n");
8348        }
8349        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8350        if (Debug.isDebuggerConnected()) {
8351            sb.append("Debugger: Connected\n");
8352        }
8353        sb.append("\n");
8354
8355        // Do the rest in a worker thread to avoid blocking the caller on I/O
8356        // (After this point, we shouldn't access AMS internal data structures.)
8357        Thread worker = new Thread("Error dump: " + dropboxTag) {
8358            @Override
8359            public void run() {
8360                if (report != null) {
8361                    sb.append(report);
8362                }
8363                if (logFile != null) {
8364                    try {
8365                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8366                    } catch (IOException e) {
8367                        Slog.e(TAG, "Error reading " + logFile, e);
8368                    }
8369                }
8370                if (crashInfo != null && crashInfo.stackTrace != null) {
8371                    sb.append(crashInfo.stackTrace);
8372                }
8373
8374                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8375                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8376                if (lines > 0) {
8377                    sb.append("\n");
8378
8379                    // Merge several logcat streams, and take the last N lines
8380                    InputStreamReader input = null;
8381                    try {
8382                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8383                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8384                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8385
8386                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8387                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8388                        input = new InputStreamReader(logcat.getInputStream());
8389
8390                        int num;
8391                        char[] buf = new char[8192];
8392                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8393                    } catch (IOException e) {
8394                        Slog.e(TAG, "Error running logcat", e);
8395                    } finally {
8396                        if (input != null) try { input.close(); } catch (IOException e) {}
8397                    }
8398                }
8399
8400                dbox.addText(dropboxTag, sb.toString());
8401            }
8402        };
8403
8404        if (process == null) {
8405            // If process is null, we are being called from some internal code
8406            // and may be about to die -- run this synchronously.
8407            worker.run();
8408        } else {
8409            worker.start();
8410        }
8411    }
8412
8413    /**
8414     * Bring up the "unexpected error" dialog box for a crashing app.
8415     * Deal with edge cases (intercepts from instrumented applications,
8416     * ActivityController, error intent receivers, that sort of thing).
8417     * @param r the application crashing
8418     * @param crashInfo describing the failure
8419     */
8420    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8421        long timeMillis = System.currentTimeMillis();
8422        String shortMsg = crashInfo.exceptionClassName;
8423        String longMsg = crashInfo.exceptionMessage;
8424        String stackTrace = crashInfo.stackTrace;
8425        if (shortMsg != null && longMsg != null) {
8426            longMsg = shortMsg + ": " + longMsg;
8427        } else if (shortMsg != null) {
8428            longMsg = shortMsg;
8429        }
8430
8431        AppErrorResult result = new AppErrorResult();
8432        synchronized (this) {
8433            if (mController != null) {
8434                try {
8435                    String name = r != null ? r.processName : null;
8436                    int pid = r != null ? r.pid : Binder.getCallingPid();
8437                    if (!mController.appCrashed(name, pid,
8438                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8439                        Slog.w(TAG, "Force-killing crashed app " + name
8440                                + " at watcher's request");
8441                        Process.killProcess(pid);
8442                        return;
8443                    }
8444                } catch (RemoteException e) {
8445                    mController = null;
8446                }
8447            }
8448
8449            final long origId = Binder.clearCallingIdentity();
8450
8451            // If this process is running instrumentation, finish it.
8452            if (r != null && r.instrumentationClass != null) {
8453                Slog.w(TAG, "Error in app " + r.processName
8454                      + " running instrumentation " + r.instrumentationClass + ":");
8455                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8456                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8457                Bundle info = new Bundle();
8458                info.putString("shortMsg", shortMsg);
8459                info.putString("longMsg", longMsg);
8460                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8461                Binder.restoreCallingIdentity(origId);
8462                return;
8463            }
8464
8465            // If we can't identify the process or it's already exceeded its crash quota,
8466            // quit right away without showing a crash dialog.
8467            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8468                Binder.restoreCallingIdentity(origId);
8469                return;
8470            }
8471
8472            Message msg = Message.obtain();
8473            msg.what = SHOW_ERROR_MSG;
8474            HashMap data = new HashMap();
8475            data.put("result", result);
8476            data.put("app", r);
8477            msg.obj = data;
8478            mHandler.sendMessage(msg);
8479
8480            Binder.restoreCallingIdentity(origId);
8481        }
8482
8483        int res = result.get();
8484
8485        Intent appErrorIntent = null;
8486        synchronized (this) {
8487            if (r != null && !r.isolated) {
8488                // XXX Can't keep track of crash time for isolated processes,
8489                // since they don't have a persistent identity.
8490                mProcessCrashTimes.put(r.info.processName, r.uid,
8491                        SystemClock.uptimeMillis());
8492            }
8493            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8494                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8495            }
8496        }
8497
8498        if (appErrorIntent != null) {
8499            try {
8500                mContext.startActivity(appErrorIntent);
8501            } catch (ActivityNotFoundException e) {
8502                Slog.w(TAG, "bug report receiver dissappeared", e);
8503            }
8504        }
8505    }
8506
8507    Intent createAppErrorIntentLocked(ProcessRecord r,
8508            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8509        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8510        if (report == null) {
8511            return null;
8512        }
8513        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8514        result.setComponent(r.errorReportReceiver);
8515        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8516        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8517        return result;
8518    }
8519
8520    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8521            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8522        if (r.errorReportReceiver == null) {
8523            return null;
8524        }
8525
8526        if (!r.crashing && !r.notResponding) {
8527            return null;
8528        }
8529
8530        ApplicationErrorReport report = new ApplicationErrorReport();
8531        report.packageName = r.info.packageName;
8532        report.installerPackageName = r.errorReportReceiver.getPackageName();
8533        report.processName = r.processName;
8534        report.time = timeMillis;
8535        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8536
8537        if (r.crashing) {
8538            report.type = ApplicationErrorReport.TYPE_CRASH;
8539            report.crashInfo = crashInfo;
8540        } else if (r.notResponding) {
8541            report.type = ApplicationErrorReport.TYPE_ANR;
8542            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8543
8544            report.anrInfo.activity = r.notRespondingReport.tag;
8545            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8546            report.anrInfo.info = r.notRespondingReport.longMsg;
8547        }
8548
8549        return report;
8550    }
8551
8552    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8553        enforceNotIsolatedCaller("getProcessesInErrorState");
8554        // assume our apps are happy - lazy create the list
8555        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8556
8557        final boolean allUsers = ActivityManager.checkUidPermission(
8558                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8559                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8560        int userId = UserHandle.getUserId(Binder.getCallingUid());
8561
8562        synchronized (this) {
8563
8564            // iterate across all processes
8565            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8566                ProcessRecord app = mLruProcesses.get(i);
8567                if (!allUsers && app.userId != userId) {
8568                    continue;
8569                }
8570                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8571                    // This one's in trouble, so we'll generate a report for it
8572                    // crashes are higher priority (in case there's a crash *and* an anr)
8573                    ActivityManager.ProcessErrorStateInfo report = null;
8574                    if (app.crashing) {
8575                        report = app.crashingReport;
8576                    } else if (app.notResponding) {
8577                        report = app.notRespondingReport;
8578                    }
8579
8580                    if (report != null) {
8581                        if (errList == null) {
8582                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8583                        }
8584                        errList.add(report);
8585                    } else {
8586                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8587                                " crashing = " + app.crashing +
8588                                " notResponding = " + app.notResponding);
8589                    }
8590                }
8591            }
8592        }
8593
8594        return errList;
8595    }
8596
8597    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8598        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8599            if (currApp != null) {
8600                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8601            }
8602            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8603        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8604            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8605        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8606            if (currApp != null) {
8607                currApp.lru = 0;
8608            }
8609            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8610        } else if (adj >= ProcessList.SERVICE_ADJ) {
8611            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8612        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8613            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8614        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8615            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8616        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8617            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8618        } else {
8619            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8620        }
8621    }
8622
8623    private void fillInProcMemInfo(ProcessRecord app,
8624            ActivityManager.RunningAppProcessInfo outInfo) {
8625        outInfo.pid = app.pid;
8626        outInfo.uid = app.info.uid;
8627        if (mHeavyWeightProcess == app) {
8628            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8629        }
8630        if (app.persistent) {
8631            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8632        }
8633        if (app.hasActivities) {
8634            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8635        }
8636        outInfo.lastTrimLevel = app.trimMemoryLevel;
8637        int adj = app.curAdj;
8638        outInfo.importance = oomAdjToImportance(adj, outInfo);
8639        outInfo.importanceReasonCode = app.adjTypeCode;
8640    }
8641
8642    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8643        enforceNotIsolatedCaller("getRunningAppProcesses");
8644        // Lazy instantiation of list
8645        List<ActivityManager.RunningAppProcessInfo> runList = null;
8646        final boolean allUsers = ActivityManager.checkUidPermission(
8647                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8648                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8649        int userId = UserHandle.getUserId(Binder.getCallingUid());
8650        synchronized (this) {
8651            // Iterate across all processes
8652            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8653                ProcessRecord app = mLruProcesses.get(i);
8654                if (!allUsers && app.userId != userId) {
8655                    continue;
8656                }
8657                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8658                    // Generate process state info for running application
8659                    ActivityManager.RunningAppProcessInfo currApp =
8660                        new ActivityManager.RunningAppProcessInfo(app.processName,
8661                                app.pid, app.getPackageList());
8662                    fillInProcMemInfo(app, currApp);
8663                    if (app.adjSource instanceof ProcessRecord) {
8664                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8665                        currApp.importanceReasonImportance = oomAdjToImportance(
8666                                app.adjSourceOom, null);
8667                    } else if (app.adjSource instanceof ActivityRecord) {
8668                        ActivityRecord r = (ActivityRecord)app.adjSource;
8669                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8670                    }
8671                    if (app.adjTarget instanceof ComponentName) {
8672                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8673                    }
8674                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8675                    //        + " lru=" + currApp.lru);
8676                    if (runList == null) {
8677                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8678                    }
8679                    runList.add(currApp);
8680                }
8681            }
8682        }
8683        return runList;
8684    }
8685
8686    public List<ApplicationInfo> getRunningExternalApplications() {
8687        enforceNotIsolatedCaller("getRunningExternalApplications");
8688        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8689        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8690        if (runningApps != null && runningApps.size() > 0) {
8691            Set<String> extList = new HashSet<String>();
8692            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8693                if (app.pkgList != null) {
8694                    for (String pkg : app.pkgList) {
8695                        extList.add(pkg);
8696                    }
8697                }
8698            }
8699            IPackageManager pm = AppGlobals.getPackageManager();
8700            for (String pkg : extList) {
8701                try {
8702                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8703                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8704                        retList.add(info);
8705                    }
8706                } catch (RemoteException e) {
8707                }
8708            }
8709        }
8710        return retList;
8711    }
8712
8713    @Override
8714    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8715        enforceNotIsolatedCaller("getMyMemoryState");
8716        synchronized (this) {
8717            ProcessRecord proc;
8718            synchronized (mPidsSelfLocked) {
8719                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8720            }
8721            fillInProcMemInfo(proc, outInfo);
8722        }
8723    }
8724
8725    @Override
8726    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8727        if (checkCallingPermission(android.Manifest.permission.DUMP)
8728                != PackageManager.PERMISSION_GRANTED) {
8729            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8730                    + Binder.getCallingPid()
8731                    + ", uid=" + Binder.getCallingUid()
8732                    + " without permission "
8733                    + android.Manifest.permission.DUMP);
8734            return;
8735        }
8736
8737        boolean dumpAll = false;
8738        boolean dumpClient = false;
8739        String dumpPackage = null;
8740
8741        int opti = 0;
8742        while (opti < args.length) {
8743            String opt = args[opti];
8744            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8745                break;
8746            }
8747            opti++;
8748            if ("-a".equals(opt)) {
8749                dumpAll = true;
8750            } else if ("-c".equals(opt)) {
8751                dumpClient = true;
8752            } else if ("-h".equals(opt)) {
8753                pw.println("Activity manager dump options:");
8754                pw.println("  [-a] [-c] [-h] [cmd] ...");
8755                pw.println("  cmd may be one of:");
8756                pw.println("    a[ctivities]: activity stack state");
8757                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8758                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8759                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8760                pw.println("    o[om]: out of memory management");
8761                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8762                pw.println("    provider [COMP_SPEC]: provider client-side state");
8763                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8764                pw.println("    service [COMP_SPEC]: service client-side state");
8765                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8766                pw.println("    all: dump all activities");
8767                pw.println("    top: dump the top activity");
8768                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8769                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8770                pw.println("    a partial substring in a component name, a");
8771                pw.println("    hex object identifier.");
8772                pw.println("  -a: include all available server state.");
8773                pw.println("  -c: include client state.");
8774                return;
8775            } else {
8776                pw.println("Unknown argument: " + opt + "; use -h for help");
8777            }
8778        }
8779
8780        long origId = Binder.clearCallingIdentity();
8781        boolean more = false;
8782        // Is the caller requesting to dump a particular piece of data?
8783        if (opti < args.length) {
8784            String cmd = args[opti];
8785            opti++;
8786            if ("activities".equals(cmd) || "a".equals(cmd)) {
8787                synchronized (this) {
8788                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8789                }
8790            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8791                String[] newArgs;
8792                String name;
8793                if (opti >= args.length) {
8794                    name = null;
8795                    newArgs = EMPTY_STRING_ARRAY;
8796                } else {
8797                    name = args[opti];
8798                    opti++;
8799                    newArgs = new String[args.length - opti];
8800                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8801                            args.length - opti);
8802                }
8803                synchronized (this) {
8804                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8805                }
8806            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8807                String[] newArgs;
8808                String name;
8809                if (opti >= args.length) {
8810                    name = null;
8811                    newArgs = EMPTY_STRING_ARRAY;
8812                } else {
8813                    name = args[opti];
8814                    opti++;
8815                    newArgs = new String[args.length - opti];
8816                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8817                            args.length - opti);
8818                }
8819                synchronized (this) {
8820                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8821                }
8822            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8823                String[] newArgs;
8824                String name;
8825                if (opti >= args.length) {
8826                    name = null;
8827                    newArgs = EMPTY_STRING_ARRAY;
8828                } else {
8829                    name = args[opti];
8830                    opti++;
8831                    newArgs = new String[args.length - opti];
8832                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8833                            args.length - opti);
8834                }
8835                synchronized (this) {
8836                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8837                }
8838            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8839                synchronized (this) {
8840                    dumpOomLocked(fd, pw, args, opti, true);
8841                }
8842            } else if ("provider".equals(cmd)) {
8843                String[] newArgs;
8844                String name;
8845                if (opti >= args.length) {
8846                    name = null;
8847                    newArgs = EMPTY_STRING_ARRAY;
8848                } else {
8849                    name = args[opti];
8850                    opti++;
8851                    newArgs = new String[args.length - opti];
8852                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8853                }
8854                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8855                    pw.println("No providers match: " + name);
8856                    pw.println("Use -h for help.");
8857                }
8858            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8859                synchronized (this) {
8860                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8861                }
8862            } else if ("service".equals(cmd)) {
8863                String[] newArgs;
8864                String name;
8865                if (opti >= args.length) {
8866                    name = null;
8867                    newArgs = EMPTY_STRING_ARRAY;
8868                } else {
8869                    name = args[opti];
8870                    opti++;
8871                    newArgs = new String[args.length - opti];
8872                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8873                            args.length - opti);
8874                }
8875                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8876                    pw.println("No services match: " + name);
8877                    pw.println("Use -h for help.");
8878                }
8879            } else if ("package".equals(cmd)) {
8880                String[] newArgs;
8881                if (opti >= args.length) {
8882                    pw.println("package: no package name specified");
8883                    pw.println("Use -h for help.");
8884                } else {
8885                    dumpPackage = args[opti];
8886                    opti++;
8887                    newArgs = new String[args.length - opti];
8888                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8889                            args.length - opti);
8890                    args = newArgs;
8891                    opti = 0;
8892                    more = true;
8893                }
8894            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8895                synchronized (this) {
8896                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8897                }
8898            } else {
8899                // Dumping a single activity?
8900                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8901                    pw.println("Bad activity command, or no activities match: " + cmd);
8902                    pw.println("Use -h for help.");
8903                }
8904            }
8905            if (!more) {
8906                Binder.restoreCallingIdentity(origId);
8907                return;
8908            }
8909        }
8910
8911        // No piece of data specified, dump everything.
8912        synchronized (this) {
8913            boolean needSep;
8914            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8915            if (needSep) {
8916                pw.println(" ");
8917            }
8918            if (dumpAll) {
8919                pw.println("-------------------------------------------------------------------------------");
8920            }
8921            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8922            if (needSep) {
8923                pw.println(" ");
8924            }
8925            if (dumpAll) {
8926                pw.println("-------------------------------------------------------------------------------");
8927            }
8928            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8929            if (needSep) {
8930                pw.println(" ");
8931            }
8932            if (dumpAll) {
8933                pw.println("-------------------------------------------------------------------------------");
8934            }
8935            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8936            if (needSep) {
8937                pw.println(" ");
8938            }
8939            if (dumpAll) {
8940                pw.println("-------------------------------------------------------------------------------");
8941            }
8942            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8943            if (needSep) {
8944                pw.println(" ");
8945            }
8946            if (dumpAll) {
8947                pw.println("-------------------------------------------------------------------------------");
8948            }
8949            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8950        }
8951        Binder.restoreCallingIdentity(origId);
8952    }
8953
8954    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8955            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8956        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8957        pw.println("  Main stack:");
8958        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8959                dumpPackage);
8960        pw.println(" ");
8961        pw.println("  Running activities (most recent first):");
8962        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8963                dumpPackage);
8964        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8965            pw.println(" ");
8966            pw.println("  Activities waiting for another to become visible:");
8967            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8968                    !dumpAll, false, dumpPackage);
8969        }
8970        if (mMainStack.mStoppingActivities.size() > 0) {
8971            pw.println(" ");
8972            pw.println("  Activities waiting to stop:");
8973            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8974                    !dumpAll, false, dumpPackage);
8975        }
8976        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8977            pw.println(" ");
8978            pw.println("  Activities waiting to sleep:");
8979            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8980                    !dumpAll, false, dumpPackage);
8981        }
8982        if (mMainStack.mFinishingActivities.size() > 0) {
8983            pw.println(" ");
8984            pw.println("  Activities waiting to finish:");
8985            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8986                    !dumpAll, false, dumpPackage);
8987        }
8988
8989        pw.println(" ");
8990        if (mMainStack.mPausingActivity != null) {
8991            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8992        }
8993        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8994        pw.println("  mFocusedActivity: " + mFocusedActivity);
8995        if (dumpAll) {
8996            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8997            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8998            pw.println("  mDismissKeyguardOnNextActivity: "
8999                    + mMainStack.mDismissKeyguardOnNextActivity);
9000        }
9001
9002        if (mRecentTasks.size() > 0) {
9003            pw.println();
9004            pw.println("  Recent tasks:");
9005
9006            final int N = mRecentTasks.size();
9007            for (int i=0; i<N; i++) {
9008                TaskRecord tr = mRecentTasks.get(i);
9009                if (dumpPackage != null) {
9010                    if (tr.realActivity == null ||
9011                            !dumpPackage.equals(tr.realActivity)) {
9012                        continue;
9013                    }
9014                }
9015                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9016                        pw.println(tr);
9017                if (dumpAll) {
9018                    mRecentTasks.get(i).dump(pw, "    ");
9019                }
9020            }
9021        }
9022
9023        if (dumpAll) {
9024            pw.println(" ");
9025            pw.println("  mCurTask: " + mCurTask);
9026        }
9027
9028        return true;
9029    }
9030
9031    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9032            int opti, boolean dumpAll, String dumpPackage) {
9033        boolean needSep = false;
9034        int numPers = 0;
9035
9036        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9037
9038        if (dumpAll) {
9039            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9040                final int NA = procs.size();
9041                for (int ia=0; ia<NA; ia++) {
9042                    ProcessRecord r = procs.valueAt(ia);
9043                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9044                        continue;
9045                    }
9046                    if (!needSep) {
9047                        pw.println("  All known processes:");
9048                        needSep = true;
9049                    }
9050                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9051                        pw.print(" UID "); pw.print(procs.keyAt(ia));
9052                        pw.print(" "); pw.println(r);
9053                    r.dump(pw, "    ");
9054                    if (r.persistent) {
9055                        numPers++;
9056                    }
9057                }
9058            }
9059        }
9060
9061        if (mIsolatedProcesses.size() > 0) {
9062            if (needSep) pw.println(" ");
9063            needSep = true;
9064            pw.println("  Isolated process list (sorted by uid):");
9065            for (int i=0; i<mIsolatedProcesses.size(); i++) {
9066                ProcessRecord r = mIsolatedProcesses.valueAt(i);
9067                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9068                    continue;
9069                }
9070                pw.println(String.format("%sIsolated #%2d: %s",
9071                        "    ", i, r.toString()));
9072            }
9073        }
9074
9075        if (mLruProcesses.size() > 0) {
9076            if (needSep) pw.println(" ");
9077            needSep = true;
9078            pw.println("  Process LRU list (sorted by oom_adj):");
9079            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9080                    "Proc", "PERS", false, dumpPackage);
9081            needSep = true;
9082        }
9083
9084        if (dumpAll) {
9085            synchronized (mPidsSelfLocked) {
9086                boolean printed = false;
9087                for (int i=0; i<mPidsSelfLocked.size(); i++) {
9088                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
9089                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9090                        continue;
9091                    }
9092                    if (!printed) {
9093                        if (needSep) pw.println(" ");
9094                        needSep = true;
9095                        pw.println("  PID mappings:");
9096                        printed = true;
9097                    }
9098                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9099                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9100                }
9101            }
9102        }
9103
9104        if (mForegroundProcesses.size() > 0) {
9105            synchronized (mPidsSelfLocked) {
9106                boolean printed = false;
9107                for (int i=0; i<mForegroundProcesses.size(); i++) {
9108                    ProcessRecord r = mPidsSelfLocked.get(
9109                            mForegroundProcesses.valueAt(i).pid);
9110                    if (dumpPackage != null && (r == null
9111                            || !dumpPackage.equals(r.info.packageName))) {
9112                        continue;
9113                    }
9114                    if (!printed) {
9115                        if (needSep) pw.println(" ");
9116                        needSep = true;
9117                        pw.println("  Foreground Processes:");
9118                        printed = true;
9119                    }
9120                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9121                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9122                }
9123            }
9124        }
9125
9126        if (mPersistentStartingProcesses.size() > 0) {
9127            if (needSep) pw.println(" ");
9128            needSep = true;
9129            pw.println("  Persisent processes that are starting:");
9130            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9131                    "Starting Norm", "Restarting PERS", dumpPackage);
9132        }
9133
9134        if (mRemovedProcesses.size() > 0) {
9135            if (needSep) pw.println(" ");
9136            needSep = true;
9137            pw.println("  Processes that are being removed:");
9138            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9139                    "Removed Norm", "Removed PERS", dumpPackage);
9140        }
9141
9142        if (mProcessesOnHold.size() > 0) {
9143            if (needSep) pw.println(" ");
9144            needSep = true;
9145            pw.println("  Processes that are on old until the system is ready:");
9146            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9147                    "OnHold Norm", "OnHold PERS", dumpPackage);
9148        }
9149
9150        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9151
9152        if (mProcessCrashTimes.getMap().size() > 0) {
9153            boolean printed = false;
9154            long now = SystemClock.uptimeMillis();
9155            for (Map.Entry<String, SparseArray<Long>> procs
9156                    : mProcessCrashTimes.getMap().entrySet()) {
9157                String pname = procs.getKey();
9158                SparseArray<Long> uids = procs.getValue();
9159                final int N = uids.size();
9160                for (int i=0; i<N; i++) {
9161                    int puid = uids.keyAt(i);
9162                    ProcessRecord r = mProcessNames.get(pname, puid);
9163                    if (dumpPackage != null && (r == null
9164                            || !dumpPackage.equals(r.info.packageName))) {
9165                        continue;
9166                    }
9167                    if (!printed) {
9168                        if (needSep) pw.println(" ");
9169                        needSep = true;
9170                        pw.println("  Time since processes crashed:");
9171                        printed = true;
9172                    }
9173                    pw.print("    Process "); pw.print(pname);
9174                            pw.print(" uid "); pw.print(puid);
9175                            pw.print(": last crashed ");
9176                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9177                            pw.println(" ago");
9178                }
9179            }
9180        }
9181
9182        if (mBadProcesses.getMap().size() > 0) {
9183            boolean printed = false;
9184            for (Map.Entry<String, SparseArray<Long>> procs
9185                    : mBadProcesses.getMap().entrySet()) {
9186                String pname = procs.getKey();
9187                SparseArray<Long> uids = procs.getValue();
9188                final int N = uids.size();
9189                for (int i=0; i<N; i++) {
9190                    int puid = uids.keyAt(i);
9191                    ProcessRecord r = mProcessNames.get(pname, puid);
9192                    if (dumpPackage != null && (r == null
9193                            || !dumpPackage.equals(r.info.packageName))) {
9194                        continue;
9195                    }
9196                    if (!printed) {
9197                        if (needSep) pw.println(" ");
9198                        needSep = true;
9199                        pw.println("  Bad processes:");
9200                    }
9201                    pw.print("    Bad process "); pw.print(pname);
9202                            pw.print(" uid "); pw.print(puid);
9203                            pw.print(": crashed at time ");
9204                            pw.println(uids.valueAt(i));
9205                }
9206            }
9207        }
9208
9209        pw.println();
9210        pw.println("  mStartedUsers:");
9211        for (int i=0; i<mStartedUsers.size(); i++) {
9212            UserStartedState uss = mStartedUsers.valueAt(i);
9213            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9214                    pw.print(": "); uss.dump("", pw);
9215        }
9216        pw.print("  mUserLru: [");
9217        for (int i=0; i<mUserLru.size(); i++) {
9218            if (i > 0) pw.print(", ");
9219            pw.print(mUserLru.get(i));
9220        }
9221        pw.println("]");
9222        pw.println("  mHomeProcess: " + mHomeProcess);
9223        pw.println("  mPreviousProcess: " + mPreviousProcess);
9224        if (dumpAll) {
9225            StringBuilder sb = new StringBuilder(128);
9226            sb.append("  mPreviousProcessVisibleTime: ");
9227            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9228            pw.println(sb);
9229        }
9230        if (mHeavyWeightProcess != null) {
9231            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9232        }
9233        pw.println("  mConfiguration: " + mConfiguration);
9234        if (dumpAll) {
9235            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9236            if (mCompatModePackages.getPackages().size() > 0) {
9237                boolean printed = false;
9238                for (Map.Entry<String, Integer> entry
9239                        : mCompatModePackages.getPackages().entrySet()) {
9240                    String pkg = entry.getKey();
9241                    int mode = entry.getValue();
9242                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9243                        continue;
9244                    }
9245                    if (!printed) {
9246                        pw.println("  mScreenCompatPackages:");
9247                        printed = true;
9248                    }
9249                    pw.print("    "); pw.print(pkg); pw.print(": ");
9250                            pw.print(mode); pw.println();
9251                }
9252            }
9253        }
9254        if (mSleeping || mWentToSleep || mLockScreenShown) {
9255            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9256                    + " mLockScreenShown " + mLockScreenShown);
9257        }
9258        if (mShuttingDown) {
9259            pw.println("  mShuttingDown=" + mShuttingDown);
9260        }
9261        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9262                || mOrigWaitForDebugger) {
9263            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9264                    + " mDebugTransient=" + mDebugTransient
9265                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9266        }
9267        if (mOpenGlTraceApp != null) {
9268            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9269        }
9270        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9271                || mProfileFd != null) {
9272            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9273            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9274            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9275                    + mAutoStopProfiler);
9276        }
9277        if (mAlwaysFinishActivities || mController != null) {
9278            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9279                    + " mController=" + mController);
9280        }
9281        if (dumpAll) {
9282            pw.println("  Total persistent processes: " + numPers);
9283            pw.println("  mStartRunning=" + mStartRunning
9284                    + " mProcessesReady=" + mProcessesReady
9285                    + " mSystemReady=" + mSystemReady);
9286            pw.println("  mBooting=" + mBooting
9287                    + " mBooted=" + mBooted
9288                    + " mFactoryTest=" + mFactoryTest);
9289            pw.print("  mLastPowerCheckRealtime=");
9290                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9291                    pw.println("");
9292            pw.print("  mLastPowerCheckUptime=");
9293                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9294                    pw.println("");
9295            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9296            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9297            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9298            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9299                    + " mNumHiddenProcs=" + mNumHiddenProcs
9300                    + " mNumServiceProcs=" + mNumServiceProcs
9301                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9302        }
9303
9304        return true;
9305    }
9306
9307    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9308            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9309        if (mProcessesToGc.size() > 0) {
9310            boolean printed = false;
9311            long now = SystemClock.uptimeMillis();
9312            for (int i=0; i<mProcessesToGc.size(); i++) {
9313                ProcessRecord proc = mProcessesToGc.get(i);
9314                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9315                    continue;
9316                }
9317                if (!printed) {
9318                    if (needSep) pw.println(" ");
9319                    needSep = true;
9320                    pw.println("  Processes that are waiting to GC:");
9321                    printed = true;
9322                }
9323                pw.print("    Process "); pw.println(proc);
9324                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9325                        pw.print(", last gced=");
9326                        pw.print(now-proc.lastRequestedGc);
9327                        pw.print(" ms ago, last lowMem=");
9328                        pw.print(now-proc.lastLowMemory);
9329                        pw.println(" ms ago");
9330
9331            }
9332        }
9333        return needSep;
9334    }
9335
9336    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9337            int opti, boolean dumpAll) {
9338        boolean needSep = false;
9339
9340        if (mLruProcesses.size() > 0) {
9341            if (needSep) pw.println(" ");
9342            needSep = true;
9343            pw.println("  OOM levels:");
9344            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9345            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9346            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9347            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9348            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9349            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9350            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9351            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9352            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9353            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9354            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9355            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9356            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9357
9358            if (needSep) pw.println(" ");
9359            needSep = true;
9360            pw.println("  Process OOM control:");
9361            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9362                    "Proc", "PERS", true, null);
9363            needSep = true;
9364        }
9365
9366        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9367
9368        pw.println();
9369        pw.println("  mHomeProcess: " + mHomeProcess);
9370        pw.println("  mPreviousProcess: " + mPreviousProcess);
9371        if (mHeavyWeightProcess != null) {
9372            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9373        }
9374
9375        return true;
9376    }
9377
9378    /**
9379     * There are three ways to call this:
9380     *  - no provider specified: dump all the providers
9381     *  - a flattened component name that matched an existing provider was specified as the
9382     *    first arg: dump that one provider
9383     *  - the first arg isn't the flattened component name of an existing provider:
9384     *    dump all providers whose component contains the first arg as a substring
9385     */
9386    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9387            int opti, boolean dumpAll) {
9388        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9389    }
9390
9391    static class ItemMatcher {
9392        ArrayList<ComponentName> components;
9393        ArrayList<String> strings;
9394        ArrayList<Integer> objects;
9395        boolean all;
9396
9397        ItemMatcher() {
9398            all = true;
9399        }
9400
9401        void build(String name) {
9402            ComponentName componentName = ComponentName.unflattenFromString(name);
9403            if (componentName != null) {
9404                if (components == null) {
9405                    components = new ArrayList<ComponentName>();
9406                }
9407                components.add(componentName);
9408                all = false;
9409            } else {
9410                int objectId = 0;
9411                // Not a '/' separated full component name; maybe an object ID?
9412                try {
9413                    objectId = Integer.parseInt(name, 16);
9414                    if (objects == null) {
9415                        objects = new ArrayList<Integer>();
9416                    }
9417                    objects.add(objectId);
9418                    all = false;
9419                } catch (RuntimeException e) {
9420                    // Not an integer; just do string match.
9421                    if (strings == null) {
9422                        strings = new ArrayList<String>();
9423                    }
9424                    strings.add(name);
9425                    all = false;
9426                }
9427            }
9428        }
9429
9430        int build(String[] args, int opti) {
9431            for (; opti<args.length; opti++) {
9432                String name = args[opti];
9433                if ("--".equals(name)) {
9434                    return opti+1;
9435                }
9436                build(name);
9437            }
9438            return opti;
9439        }
9440
9441        boolean match(Object object, ComponentName comp) {
9442            if (all) {
9443                return true;
9444            }
9445            if (components != null) {
9446                for (int i=0; i<components.size(); i++) {
9447                    if (components.get(i).equals(comp)) {
9448                        return true;
9449                    }
9450                }
9451            }
9452            if (objects != null) {
9453                for (int i=0; i<objects.size(); i++) {
9454                    if (System.identityHashCode(object) == objects.get(i)) {
9455                        return true;
9456                    }
9457                }
9458            }
9459            if (strings != null) {
9460                String flat = comp.flattenToString();
9461                for (int i=0; i<strings.size(); i++) {
9462                    if (flat.contains(strings.get(i))) {
9463                        return true;
9464                    }
9465                }
9466            }
9467            return false;
9468        }
9469    }
9470
9471    /**
9472     * There are three things that cmd can be:
9473     *  - a flattened component name that matches an existing activity
9474     *  - the cmd arg isn't the flattened component name of an existing activity:
9475     *    dump all activity whose component contains the cmd as a substring
9476     *  - A hex number of the ActivityRecord object instance.
9477     */
9478    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9479            int opti, boolean dumpAll) {
9480        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9481
9482        if ("all".equals(name)) {
9483            synchronized (this) {
9484                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9485                    activities.add(r1);
9486                }
9487            }
9488        } else if ("top".equals(name)) {
9489            synchronized (this) {
9490                final int N = mMainStack.mHistory.size();
9491                if (N > 0) {
9492                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9493                }
9494            }
9495        } else {
9496            ItemMatcher matcher = new ItemMatcher();
9497            matcher.build(name);
9498
9499            synchronized (this) {
9500                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9501                    if (matcher.match(r1, r1.intent.getComponent())) {
9502                        activities.add(r1);
9503                    }
9504                }
9505            }
9506        }
9507
9508        if (activities.size() <= 0) {
9509            return false;
9510        }
9511
9512        String[] newArgs = new String[args.length - opti];
9513        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9514
9515        TaskRecord lastTask = null;
9516        boolean needSep = false;
9517        for (int i=activities.size()-1; i>=0; i--) {
9518            ActivityRecord r = (ActivityRecord)activities.get(i);
9519            if (needSep) {
9520                pw.println();
9521            }
9522            needSep = true;
9523            synchronized (this) {
9524                if (lastTask != r.task) {
9525                    lastTask = r.task;
9526                    pw.print("TASK "); pw.print(lastTask.affinity);
9527                            pw.print(" id="); pw.println(lastTask.taskId);
9528                    if (dumpAll) {
9529                        lastTask.dump(pw, "  ");
9530                    }
9531                }
9532            }
9533            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9534        }
9535        return true;
9536    }
9537
9538    /**
9539     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9540     * there is a thread associated with the activity.
9541     */
9542    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9543            final ActivityRecord r, String[] args, boolean dumpAll) {
9544        String innerPrefix = prefix + "  ";
9545        synchronized (this) {
9546            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9547                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9548                    pw.print(" pid=");
9549                    if (r.app != null) pw.println(r.app.pid);
9550                    else pw.println("(not running)");
9551            if (dumpAll) {
9552                r.dump(pw, innerPrefix);
9553            }
9554        }
9555        if (r.app != null && r.app.thread != null) {
9556            // flush anything that is already in the PrintWriter since the thread is going
9557            // to write to the file descriptor directly
9558            pw.flush();
9559            try {
9560                TransferPipe tp = new TransferPipe();
9561                try {
9562                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9563                            r.appToken, innerPrefix, args);
9564                    tp.go(fd);
9565                } finally {
9566                    tp.kill();
9567                }
9568            } catch (IOException e) {
9569                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9570            } catch (RemoteException e) {
9571                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9572            }
9573        }
9574    }
9575
9576    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9577            int opti, boolean dumpAll, String dumpPackage) {
9578        boolean needSep = false;
9579        boolean onlyHistory = false;
9580
9581        if ("history".equals(dumpPackage)) {
9582            onlyHistory = true;
9583            dumpPackage = null;
9584        }
9585
9586        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9587        if (!onlyHistory && dumpAll) {
9588            if (mRegisteredReceivers.size() > 0) {
9589                boolean printed = false;
9590                Iterator it = mRegisteredReceivers.values().iterator();
9591                while (it.hasNext()) {
9592                    ReceiverList r = (ReceiverList)it.next();
9593                    if (dumpPackage != null && (r.app == null ||
9594                            !dumpPackage.equals(r.app.info.packageName))) {
9595                        continue;
9596                    }
9597                    if (!printed) {
9598                        pw.println("  Registered Receivers:");
9599                        needSep = true;
9600                        printed = true;
9601                    }
9602                    pw.print("  * "); pw.println(r);
9603                    r.dump(pw, "    ");
9604                }
9605            }
9606
9607            if (mReceiverResolver.dump(pw, needSep ?
9608                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9609                    "    ", dumpPackage, false)) {
9610                needSep = true;
9611            }
9612        }
9613
9614        for (BroadcastQueue q : mBroadcastQueues) {
9615            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9616        }
9617
9618        needSep = true;
9619
9620        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9621            for (int user=0; user<mStickyBroadcasts.size(); user++) {
9622                if (needSep) {
9623                    pw.println();
9624                }
9625                needSep = true;
9626                pw.print("  Sticky broadcasts for user ");
9627                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9628                StringBuilder sb = new StringBuilder(128);
9629                for (Map.Entry<String, ArrayList<Intent>> ent
9630                        : mStickyBroadcasts.valueAt(user).entrySet()) {
9631                    pw.print("  * Sticky action "); pw.print(ent.getKey());
9632                    if (dumpAll) {
9633                        pw.println(":");
9634                        ArrayList<Intent> intents = ent.getValue();
9635                        final int N = intents.size();
9636                        for (int i=0; i<N; i++) {
9637                            sb.setLength(0);
9638                            sb.append("    Intent: ");
9639                            intents.get(i).toShortString(sb, false, true, false, false);
9640                            pw.println(sb.toString());
9641                            Bundle bundle = intents.get(i).getExtras();
9642                            if (bundle != null) {
9643                                pw.print("      ");
9644                                pw.println(bundle.toString());
9645                            }
9646                        }
9647                    } else {
9648                        pw.println("");
9649                    }
9650                }
9651            }
9652        }
9653
9654        if (!onlyHistory && dumpAll) {
9655            pw.println();
9656            for (BroadcastQueue queue : mBroadcastQueues) {
9657                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9658                        + queue.mBroadcastsScheduled);
9659            }
9660            pw.println("  mHandler:");
9661            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9662            needSep = true;
9663        }
9664
9665        return needSep;
9666    }
9667
9668    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9669            int opti, boolean dumpAll, String dumpPackage) {
9670        boolean needSep = true;
9671
9672        ItemMatcher matcher = new ItemMatcher();
9673        matcher.build(args, opti);
9674
9675        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9676
9677        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9678
9679        if (mLaunchingProviders.size() > 0) {
9680            boolean printed = false;
9681            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9682                ContentProviderRecord r = mLaunchingProviders.get(i);
9683                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9684                    continue;
9685                }
9686                if (!printed) {
9687                    if (needSep) pw.println(" ");
9688                    needSep = true;
9689                    pw.println("  Launching content providers:");
9690                    printed = true;
9691                }
9692                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9693                        pw.println(r);
9694            }
9695        }
9696
9697        if (mGrantedUriPermissions.size() > 0) {
9698            if (needSep) pw.println();
9699            needSep = true;
9700            pw.println("Granted Uri Permissions:");
9701            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9702                int uid = mGrantedUriPermissions.keyAt(i);
9703                HashMap<Uri, UriPermission> perms
9704                        = mGrantedUriPermissions.valueAt(i);
9705                pw.print("  * UID "); pw.print(uid);
9706                        pw.println(" holds:");
9707                for (UriPermission perm : perms.values()) {
9708                    pw.print("    "); pw.println(perm);
9709                    if (dumpAll) {
9710                        perm.dump(pw, "      ");
9711                    }
9712                }
9713            }
9714            needSep = true;
9715        }
9716
9717        return needSep;
9718    }
9719
9720    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9721            int opti, boolean dumpAll, String dumpPackage) {
9722        boolean needSep = false;
9723
9724        if (mIntentSenderRecords.size() > 0) {
9725            boolean printed = false;
9726            Iterator<WeakReference<PendingIntentRecord>> it
9727                    = mIntentSenderRecords.values().iterator();
9728            while (it.hasNext()) {
9729                WeakReference<PendingIntentRecord> ref = it.next();
9730                PendingIntentRecord rec = ref != null ? ref.get(): null;
9731                if (dumpPackage != null && (rec == null
9732                        || !dumpPackage.equals(rec.key.packageName))) {
9733                    continue;
9734                }
9735                if (!printed) {
9736                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9737                    printed = true;
9738                }
9739                needSep = true;
9740                if (rec != null) {
9741                    pw.print("  * "); pw.println(rec);
9742                    if (dumpAll) {
9743                        rec.dump(pw, "    ");
9744                    }
9745                } else {
9746                    pw.print("  * "); pw.println(ref);
9747                }
9748            }
9749        }
9750
9751        return needSep;
9752    }
9753
9754    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9755            String prefix, String label, boolean complete, boolean brief, boolean client,
9756            String dumpPackage) {
9757        TaskRecord lastTask = null;
9758        boolean needNL = false;
9759        final String innerPrefix = prefix + "      ";
9760        final String[] args = new String[0];
9761        for (int i=list.size()-1; i>=0; i--) {
9762            final ActivityRecord r = (ActivityRecord)list.get(i);
9763            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9764                continue;
9765            }
9766            final boolean full = !brief && (complete || !r.isInHistory());
9767            if (needNL) {
9768                pw.println(" ");
9769                needNL = false;
9770            }
9771            if (lastTask != r.task) {
9772                lastTask = r.task;
9773                pw.print(prefix);
9774                pw.print(full ? "* " : "  ");
9775                pw.println(lastTask);
9776                if (full) {
9777                    lastTask.dump(pw, prefix + "  ");
9778                } else if (complete) {
9779                    // Complete + brief == give a summary.  Isn't that obvious?!?
9780                    if (lastTask.intent != null) {
9781                        pw.print(prefix); pw.print("  ");
9782                                pw.println(lastTask.intent.toInsecureStringWithClip());
9783                    }
9784                }
9785            }
9786            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9787            pw.print(" #"); pw.print(i); pw.print(": ");
9788            pw.println(r);
9789            if (full) {
9790                r.dump(pw, innerPrefix);
9791            } else if (complete) {
9792                // Complete + brief == give a summary.  Isn't that obvious?!?
9793                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9794                if (r.app != null) {
9795                    pw.print(innerPrefix); pw.println(r.app);
9796                }
9797            }
9798            if (client && r.app != null && r.app.thread != null) {
9799                // flush anything that is already in the PrintWriter since the thread is going
9800                // to write to the file descriptor directly
9801                pw.flush();
9802                try {
9803                    TransferPipe tp = new TransferPipe();
9804                    try {
9805                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9806                                r.appToken, innerPrefix, args);
9807                        // Short timeout, since blocking here can
9808                        // deadlock with the application.
9809                        tp.go(fd, 2000);
9810                    } finally {
9811                        tp.kill();
9812                    }
9813                } catch (IOException e) {
9814                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9815                } catch (RemoteException e) {
9816                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9817                }
9818                needNL = true;
9819            }
9820        }
9821    }
9822
9823    private static String buildOomTag(String prefix, String space, int val, int base) {
9824        if (val == base) {
9825            if (space == null) return prefix;
9826            return prefix + "  ";
9827        }
9828        return prefix + "+" + Integer.toString(val-base);
9829    }
9830
9831    private static final int dumpProcessList(PrintWriter pw,
9832            ActivityManagerService service, List list,
9833            String prefix, String normalLabel, String persistentLabel,
9834            String dumpPackage) {
9835        int numPers = 0;
9836        final int N = list.size()-1;
9837        for (int i=N; i>=0; i--) {
9838            ProcessRecord r = (ProcessRecord)list.get(i);
9839            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9840                continue;
9841            }
9842            pw.println(String.format("%s%s #%2d: %s",
9843                    prefix, (r.persistent ? persistentLabel : normalLabel),
9844                    i, r.toString()));
9845            if (r.persistent) {
9846                numPers++;
9847            }
9848        }
9849        return numPers;
9850    }
9851
9852    private static final boolean dumpProcessOomList(PrintWriter pw,
9853            ActivityManagerService service, List<ProcessRecord> origList,
9854            String prefix, String normalLabel, String persistentLabel,
9855            boolean inclDetails, String dumpPackage) {
9856
9857        ArrayList<Pair<ProcessRecord, Integer>> list
9858                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9859        for (int i=0; i<origList.size(); i++) {
9860            ProcessRecord r = origList.get(i);
9861            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9862                continue;
9863            }
9864            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9865        }
9866
9867        if (list.size() <= 0) {
9868            return false;
9869        }
9870
9871        Comparator<Pair<ProcessRecord, Integer>> comparator
9872                = new Comparator<Pair<ProcessRecord, Integer>>() {
9873            @Override
9874            public int compare(Pair<ProcessRecord, Integer> object1,
9875                    Pair<ProcessRecord, Integer> object2) {
9876                if (object1.first.setAdj != object2.first.setAdj) {
9877                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9878                }
9879                if (object1.second.intValue() != object2.second.intValue()) {
9880                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9881                }
9882                return 0;
9883            }
9884        };
9885
9886        Collections.sort(list, comparator);
9887
9888        final long curRealtime = SystemClock.elapsedRealtime();
9889        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9890        final long curUptime = SystemClock.uptimeMillis();
9891        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9892
9893        for (int i=list.size()-1; i>=0; i--) {
9894            ProcessRecord r = list.get(i).first;
9895            String oomAdj;
9896            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9897                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9898            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9899                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9900            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9901                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9902            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9903                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9904            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9905                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9906            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9907                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9908            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9909                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9910            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9911                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9912            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9913                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9914            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9915                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9916            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9917                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9918            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9919                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9920            } else {
9921                oomAdj = Integer.toString(r.setAdj);
9922            }
9923            String schedGroup;
9924            switch (r.setSchedGroup) {
9925                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9926                    schedGroup = "B";
9927                    break;
9928                case Process.THREAD_GROUP_DEFAULT:
9929                    schedGroup = "F";
9930                    break;
9931                default:
9932                    schedGroup = Integer.toString(r.setSchedGroup);
9933                    break;
9934            }
9935            String foreground;
9936            if (r.foregroundActivities) {
9937                foreground = "A";
9938            } else if (r.foregroundServices) {
9939                foreground = "S";
9940            } else {
9941                foreground = " ";
9942            }
9943            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9944                    prefix, (r.persistent ? persistentLabel : normalLabel),
9945                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9946                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9947            if (r.adjSource != null || r.adjTarget != null) {
9948                pw.print(prefix);
9949                pw.print("    ");
9950                if (r.adjTarget instanceof ComponentName) {
9951                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9952                } else if (r.adjTarget != null) {
9953                    pw.print(r.adjTarget.toString());
9954                } else {
9955                    pw.print("{null}");
9956                }
9957                pw.print("<=");
9958                if (r.adjSource instanceof ProcessRecord) {
9959                    pw.print("Proc{");
9960                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9961                    pw.println("}");
9962                } else if (r.adjSource != null) {
9963                    pw.println(r.adjSource.toString());
9964                } else {
9965                    pw.println("{null}");
9966                }
9967            }
9968            if (inclDetails) {
9969                pw.print(prefix);
9970                pw.print("    ");
9971                pw.print("oom: max="); pw.print(r.maxAdj);
9972                pw.print(" hidden="); pw.print(r.hiddenAdj);
9973                pw.print(" empty="); pw.print(r.emptyAdj);
9974                pw.print(" curRaw="); pw.print(r.curRawAdj);
9975                pw.print(" setRaw="); pw.print(r.setRawAdj);
9976                pw.print(" cur="); pw.print(r.curAdj);
9977                pw.print(" set="); pw.println(r.setAdj);
9978                pw.print(prefix);
9979                pw.print("    ");
9980                pw.print("keeping="); pw.print(r.keeping);
9981                pw.print(" hidden="); pw.print(r.hidden);
9982                pw.print(" empty="); pw.print(r.empty);
9983                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
9984
9985                if (!r.keeping) {
9986                    if (r.lastWakeTime != 0) {
9987                        long wtime;
9988                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9989                        synchronized (stats) {
9990                            wtime = stats.getProcessWakeTime(r.info.uid,
9991                                    r.pid, curRealtime);
9992                        }
9993                        long timeUsed = wtime - r.lastWakeTime;
9994                        pw.print(prefix);
9995                        pw.print("    ");
9996                        pw.print("keep awake over ");
9997                        TimeUtils.formatDuration(realtimeSince, pw);
9998                        pw.print(" used ");
9999                        TimeUtils.formatDuration(timeUsed, pw);
10000                        pw.print(" (");
10001                        pw.print((timeUsed*100)/realtimeSince);
10002                        pw.println("%)");
10003                    }
10004                    if (r.lastCpuTime != 0) {
10005                        long timeUsed = r.curCpuTime - r.lastCpuTime;
10006                        pw.print(prefix);
10007                        pw.print("    ");
10008                        pw.print("run cpu over ");
10009                        TimeUtils.formatDuration(uptimeSince, pw);
10010                        pw.print(" used ");
10011                        TimeUtils.formatDuration(timeUsed, pw);
10012                        pw.print(" (");
10013                        pw.print((timeUsed*100)/uptimeSince);
10014                        pw.println("%)");
10015                    }
10016                }
10017            }
10018        }
10019        return true;
10020    }
10021
10022    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10023        ArrayList<ProcessRecord> procs;
10024        synchronized (this) {
10025            if (args != null && args.length > start
10026                    && args[start].charAt(0) != '-') {
10027                procs = new ArrayList<ProcessRecord>();
10028                int pid = -1;
10029                try {
10030                    pid = Integer.parseInt(args[start]);
10031                } catch (NumberFormatException e) {
10032
10033                }
10034                for (int i=mLruProcesses.size()-1; i>=0; i--) {
10035                    ProcessRecord proc = mLruProcesses.get(i);
10036                    if (proc.pid == pid) {
10037                        procs.add(proc);
10038                    } else if (proc.processName.equals(args[start])) {
10039                        procs.add(proc);
10040                    }
10041                }
10042                if (procs.size() <= 0) {
10043                    pw.println("No process found for: " + args[start]);
10044                    return null;
10045                }
10046            } else {
10047                procs = new ArrayList<ProcessRecord>(mLruProcesses);
10048            }
10049        }
10050        return procs;
10051    }
10052
10053    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10054            PrintWriter pw, String[] args) {
10055        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10056        if (procs == null) {
10057            return;
10058        }
10059
10060        long uptime = SystemClock.uptimeMillis();
10061        long realtime = SystemClock.elapsedRealtime();
10062        pw.println("Applications Graphics Acceleration Info:");
10063        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10064
10065        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10066            ProcessRecord r = procs.get(i);
10067            if (r.thread != null) {
10068                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10069                pw.flush();
10070                try {
10071                    TransferPipe tp = new TransferPipe();
10072                    try {
10073                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10074                        tp.go(fd);
10075                    } finally {
10076                        tp.kill();
10077                    }
10078                } catch (IOException e) {
10079                    pw.println("Failure while dumping the app: " + r);
10080                    pw.flush();
10081                } catch (RemoteException e) {
10082                    pw.println("Got a RemoteException while dumping the app " + r);
10083                    pw.flush();
10084                }
10085            }
10086        }
10087    }
10088
10089    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10090        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10091        if (procs == null) {
10092            return;
10093        }
10094
10095        pw.println("Applications Database Info:");
10096
10097        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10098            ProcessRecord r = procs.get(i);
10099            if (r.thread != null) {
10100                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10101                pw.flush();
10102                try {
10103                    TransferPipe tp = new TransferPipe();
10104                    try {
10105                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10106                        tp.go(fd);
10107                    } finally {
10108                        tp.kill();
10109                    }
10110                } catch (IOException e) {
10111                    pw.println("Failure while dumping the app: " + r);
10112                    pw.flush();
10113                } catch (RemoteException e) {
10114                    pw.println("Got a RemoteException while dumping the app " + r);
10115                    pw.flush();
10116                }
10117            }
10118        }
10119    }
10120
10121    final static class MemItem {
10122        final String label;
10123        final String shortLabel;
10124        final long pss;
10125        final int id;
10126        ArrayList<MemItem> subitems;
10127
10128        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10129            label = _label;
10130            shortLabel = _shortLabel;
10131            pss = _pss;
10132            id = _id;
10133        }
10134    }
10135
10136    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10137            boolean sort) {
10138        if (sort) {
10139            Collections.sort(items, new Comparator<MemItem>() {
10140                @Override
10141                public int compare(MemItem lhs, MemItem rhs) {
10142                    if (lhs.pss < rhs.pss) {
10143                        return 1;
10144                    } else if (lhs.pss > rhs.pss) {
10145                        return -1;
10146                    }
10147                    return 0;
10148                }
10149            });
10150        }
10151
10152        for (int i=0; i<items.size(); i++) {
10153            MemItem mi = items.get(i);
10154            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10155            if (mi.subitems != null) {
10156                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10157            }
10158        }
10159    }
10160
10161    // These are in KB.
10162    static final long[] DUMP_MEM_BUCKETS = new long[] {
10163        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10164        120*1024, 160*1024, 200*1024,
10165        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10166        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10167    };
10168
10169    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10170            boolean stackLike) {
10171        int start = label.lastIndexOf('.');
10172        if (start >= 0) start++;
10173        else start = 0;
10174        int end = label.length();
10175        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10176            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10177                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10178                out.append(bucket);
10179                out.append(stackLike ? "MB." : "MB ");
10180                out.append(label, start, end);
10181                return;
10182            }
10183        }
10184        out.append(memKB/1024);
10185        out.append(stackLike ? "MB." : "MB ");
10186        out.append(label, start, end);
10187    }
10188
10189    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10190            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10191            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10192            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10193            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10194    };
10195    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10196            "System", "Persistent", "Foreground",
10197            "Visible", "Perceptible", "Heavy Weight",
10198            "Backup", "A Services", "Home", "Previous",
10199            "B Services", "Background"
10200    };
10201
10202    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10203            PrintWriter pw, String prefix, String[] args, boolean brief,
10204            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10205        boolean dumpAll = false;
10206        boolean oomOnly = false;
10207
10208        int opti = 0;
10209        while (opti < args.length) {
10210            String opt = args[opti];
10211            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10212                break;
10213            }
10214            opti++;
10215            if ("-a".equals(opt)) {
10216                dumpAll = true;
10217            } else if ("--oom".equals(opt)) {
10218                oomOnly = true;
10219            } else if ("-h".equals(opt)) {
10220                pw.println("meminfo dump options: [-a] [--oom] [process]");
10221                pw.println("  -a: include all available information for each process.");
10222                pw.println("  --oom: only show processes organized by oom adj.");
10223                pw.println("If [process] is specified it can be the name or ");
10224                pw.println("pid of a specific process to dump.");
10225                return;
10226            } else {
10227                pw.println("Unknown argument: " + opt + "; use -h for help");
10228            }
10229        }
10230
10231        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10232        if (procs == null) {
10233            return;
10234        }
10235
10236        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10237        long uptime = SystemClock.uptimeMillis();
10238        long realtime = SystemClock.elapsedRealtime();
10239
10240        if (procs.size() == 1 || isCheckinRequest) {
10241            dumpAll = true;
10242        }
10243
10244        if (isCheckinRequest) {
10245            // short checkin version
10246            pw.println(uptime + "," + realtime);
10247            pw.flush();
10248        } else {
10249            pw.println("Applications Memory Usage (kB):");
10250            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10251        }
10252
10253        String[] innerArgs = new String[args.length-opti];
10254        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10255
10256        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10257        long nativePss=0, dalvikPss=0, otherPss=0;
10258        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10259
10260        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10261        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10262                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10263
10264        long totalPss = 0;
10265
10266        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10267            ProcessRecord r = procs.get(i);
10268            if (r.thread != null) {
10269                if (!isCheckinRequest && dumpAll) {
10270                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10271                    pw.flush();
10272                }
10273                Debug.MemoryInfo mi = null;
10274                if (dumpAll) {
10275                    try {
10276                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10277                    } catch (RemoteException e) {
10278                        if (!isCheckinRequest) {
10279                            pw.println("Got RemoteException!");
10280                            pw.flush();
10281                        }
10282                    }
10283                } else {
10284                    mi = new Debug.MemoryInfo();
10285                    Debug.getMemoryInfo(r.pid, mi);
10286                }
10287
10288                if (!isCheckinRequest && mi != null) {
10289                    long myTotalPss = mi.getTotalPss();
10290                    totalPss += myTotalPss;
10291                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10292                            r.processName, myTotalPss, 0);
10293                    procMems.add(pssItem);
10294
10295                    nativePss += mi.nativePss;
10296                    dalvikPss += mi.dalvikPss;
10297                    otherPss += mi.otherPss;
10298                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10299                        long mem = mi.getOtherPss(j);
10300                        miscPss[j] += mem;
10301                        otherPss -= mem;
10302                    }
10303
10304                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10305                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10306                                || oomIndex == (oomPss.length-1)) {
10307                            oomPss[oomIndex] += myTotalPss;
10308                            if (oomProcs[oomIndex] == null) {
10309                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10310                            }
10311                            oomProcs[oomIndex].add(pssItem);
10312                            break;
10313                        }
10314                    }
10315                }
10316            }
10317        }
10318
10319        if (!isCheckinRequest && procs.size() > 1) {
10320            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10321
10322            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10323            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10324            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10325            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10326                String label = Debug.MemoryInfo.getOtherLabel(j);
10327                catMems.add(new MemItem(label, label, miscPss[j], j));
10328            }
10329
10330            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10331            for (int j=0; j<oomPss.length; j++) {
10332                if (oomPss[j] != 0) {
10333                    String label = DUMP_MEM_OOM_LABEL[j];
10334                    MemItem item = new MemItem(label, label, oomPss[j],
10335                            DUMP_MEM_OOM_ADJ[j]);
10336                    item.subitems = oomProcs[j];
10337                    oomMems.add(item);
10338                }
10339            }
10340
10341            if (outTag != null || outStack != null) {
10342                if (outTag != null) {
10343                    appendMemBucket(outTag, totalPss, "total", false);
10344                }
10345                if (outStack != null) {
10346                    appendMemBucket(outStack, totalPss, "total", true);
10347                }
10348                boolean firstLine = true;
10349                for (int i=0; i<oomMems.size(); i++) {
10350                    MemItem miCat = oomMems.get(i);
10351                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10352                        continue;
10353                    }
10354                    if (miCat.id < ProcessList.SERVICE_ADJ
10355                            || miCat.id == ProcessList.HOME_APP_ADJ
10356                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10357                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10358                            outTag.append(" / ");
10359                        }
10360                        if (outStack != null) {
10361                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10362                                if (firstLine) {
10363                                    outStack.append(":");
10364                                    firstLine = false;
10365                                }
10366                                outStack.append("\n\t at ");
10367                            } else {
10368                                outStack.append("$");
10369                            }
10370                        }
10371                        for (int j=0; j<miCat.subitems.size(); j++) {
10372                            MemItem mi = miCat.subitems.get(j);
10373                            if (j > 0) {
10374                                if (outTag != null) {
10375                                    outTag.append(" ");
10376                                }
10377                                if (outStack != null) {
10378                                    outStack.append("$");
10379                                }
10380                            }
10381                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10382                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10383                            }
10384                            if (outStack != null) {
10385                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10386                            }
10387                        }
10388                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10389                            outStack.append("(");
10390                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10391                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10392                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10393                                    outStack.append(":");
10394                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10395                                }
10396                            }
10397                            outStack.append(")");
10398                        }
10399                    }
10400                }
10401            }
10402
10403            if (!brief && !oomOnly) {
10404                pw.println();
10405                pw.println("Total PSS by process:");
10406                dumpMemItems(pw, "  ", procMems, true);
10407                pw.println();
10408            }
10409            pw.println("Total PSS by OOM adjustment:");
10410            dumpMemItems(pw, "  ", oomMems, false);
10411            if (!oomOnly) {
10412                PrintWriter out = categoryPw != null ? categoryPw : pw;
10413                out.println();
10414                out.println("Total PSS by category:");
10415                dumpMemItems(out, "  ", catMems, true);
10416            }
10417            pw.println();
10418            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10419            final int[] SINGLE_LONG_FORMAT = new int[] {
10420                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10421            };
10422            long[] longOut = new long[1];
10423            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10424                    SINGLE_LONG_FORMAT, null, longOut, null);
10425            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10426            longOut[0] = 0;
10427            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10428                    SINGLE_LONG_FORMAT, null, longOut, null);
10429            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10430            longOut[0] = 0;
10431            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10432                    SINGLE_LONG_FORMAT, null, longOut, null);
10433            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10434            longOut[0] = 0;
10435            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10436                    SINGLE_LONG_FORMAT, null, longOut, null);
10437            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10438            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10439                    pw.print(shared); pw.println(" kB");
10440            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10441                    pw.print(voltile); pw.println(" kB volatile");
10442        }
10443    }
10444
10445    /**
10446     * Searches array of arguments for the specified string
10447     * @param args array of argument strings
10448     * @param value value to search for
10449     * @return true if the value is contained in the array
10450     */
10451    private static boolean scanArgs(String[] args, String value) {
10452        if (args != null) {
10453            for (String arg : args) {
10454                if (value.equals(arg)) {
10455                    return true;
10456                }
10457            }
10458        }
10459        return false;
10460    }
10461
10462    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10463            ContentProviderRecord cpr, boolean always) {
10464        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10465
10466        if (!inLaunching || always) {
10467            synchronized (cpr) {
10468                cpr.launchingApp = null;
10469                cpr.notifyAll();
10470            }
10471            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10472            String names[] = cpr.info.authority.split(";");
10473            for (int j = 0; j < names.length; j++) {
10474                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10475            }
10476        }
10477
10478        for (int i=0; i<cpr.connections.size(); i++) {
10479            ContentProviderConnection conn = cpr.connections.get(i);
10480            if (conn.waiting) {
10481                // If this connection is waiting for the provider, then we don't
10482                // need to mess with its process unless we are always removing
10483                // or for some reason the provider is not currently launching.
10484                if (inLaunching && !always) {
10485                    continue;
10486                }
10487            }
10488            ProcessRecord capp = conn.client;
10489            conn.dead = true;
10490            if (conn.stableCount > 0) {
10491                if (!capp.persistent && capp.thread != null
10492                        && capp.pid != 0
10493                        && capp.pid != MY_PID) {
10494                    Slog.i(TAG, "Kill " + capp.processName
10495                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10496                            + " in dying process " + (proc != null ? proc.processName : "??"));
10497                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10498                            capp.processName, capp.setAdj, "dying provider "
10499                                    + cpr.name.toShortString());
10500                    Process.killProcessQuiet(capp.pid);
10501                }
10502            } else if (capp.thread != null && conn.provider.provider != null) {
10503                try {
10504                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10505                } catch (RemoteException e) {
10506                }
10507                // In the protocol here, we don't expect the client to correctly
10508                // clean up this connection, we'll just remove it.
10509                cpr.connections.remove(i);
10510                conn.client.conProviders.remove(conn);
10511            }
10512        }
10513
10514        if (inLaunching && always) {
10515            mLaunchingProviders.remove(cpr);
10516        }
10517        return inLaunching;
10518    }
10519
10520    /**
10521     * Main code for cleaning up a process when it has gone away.  This is
10522     * called both as a result of the process dying, or directly when stopping
10523     * a process when running in single process mode.
10524     */
10525    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10526            boolean restarting, boolean allowRestart, int index) {
10527        if (index >= 0) {
10528            mLruProcesses.remove(index);
10529        }
10530
10531        mProcessesToGc.remove(app);
10532
10533        // Dismiss any open dialogs.
10534        if (app.crashDialog != null) {
10535            app.crashDialog.dismiss();
10536            app.crashDialog = null;
10537        }
10538        if (app.anrDialog != null) {
10539            app.anrDialog.dismiss();
10540            app.anrDialog = null;
10541        }
10542        if (app.waitDialog != null) {
10543            app.waitDialog.dismiss();
10544            app.waitDialog = null;
10545        }
10546
10547        app.crashing = false;
10548        app.notResponding = false;
10549
10550        app.resetPackageList();
10551        app.unlinkDeathRecipient();
10552        app.thread = null;
10553        app.forcingToForeground = null;
10554        app.foregroundServices = false;
10555        app.foregroundActivities = false;
10556        app.hasShownUi = false;
10557        app.hasAboveClient = false;
10558
10559        mServices.killServicesLocked(app, allowRestart);
10560
10561        boolean restart = false;
10562
10563        // Remove published content providers.
10564        if (!app.pubProviders.isEmpty()) {
10565            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10566            while (it.hasNext()) {
10567                ContentProviderRecord cpr = it.next();
10568
10569                final boolean always = app.bad || !allowRestart;
10570                if (removeDyingProviderLocked(app, cpr, always) || always) {
10571                    // We left the provider in the launching list, need to
10572                    // restart it.
10573                    restart = true;
10574                }
10575
10576                cpr.provider = null;
10577                cpr.proc = null;
10578            }
10579            app.pubProviders.clear();
10580        }
10581
10582        // Take care of any launching providers waiting for this process.
10583        if (checkAppInLaunchingProvidersLocked(app, false)) {
10584            restart = true;
10585        }
10586
10587        // Unregister from connected content providers.
10588        if (!app.conProviders.isEmpty()) {
10589            for (int i=0; i<app.conProviders.size(); i++) {
10590                ContentProviderConnection conn = app.conProviders.get(i);
10591                conn.provider.connections.remove(conn);
10592            }
10593            app.conProviders.clear();
10594        }
10595
10596        // At this point there may be remaining entries in mLaunchingProviders
10597        // where we were the only one waiting, so they are no longer of use.
10598        // Look for these and clean up if found.
10599        // XXX Commented out for now.  Trying to figure out a way to reproduce
10600        // the actual situation to identify what is actually going on.
10601        if (false) {
10602            for (int i=0; i<mLaunchingProviders.size(); i++) {
10603                ContentProviderRecord cpr = (ContentProviderRecord)
10604                        mLaunchingProviders.get(i);
10605                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10606                    synchronized (cpr) {
10607                        cpr.launchingApp = null;
10608                        cpr.notifyAll();
10609                    }
10610                }
10611            }
10612        }
10613
10614        skipCurrentReceiverLocked(app);
10615
10616        // Unregister any receivers.
10617        if (app.receivers.size() > 0) {
10618            Iterator<ReceiverList> it = app.receivers.iterator();
10619            while (it.hasNext()) {
10620                removeReceiverLocked(it.next());
10621            }
10622            app.receivers.clear();
10623        }
10624
10625        // If the app is undergoing backup, tell the backup manager about it
10626        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10627            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10628            try {
10629                IBackupManager bm = IBackupManager.Stub.asInterface(
10630                        ServiceManager.getService(Context.BACKUP_SERVICE));
10631                bm.agentDisconnected(app.info.packageName);
10632            } catch (RemoteException e) {
10633                // can't happen; backup manager is local
10634            }
10635        }
10636
10637        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10638            ProcessChangeItem item = mPendingProcessChanges.get(i);
10639            if (item.pid == app.pid) {
10640                mPendingProcessChanges.remove(i);
10641                mAvailProcessChanges.add(item);
10642            }
10643        }
10644        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10645
10646        // If the caller is restarting this app, then leave it in its
10647        // current lists and let the caller take care of it.
10648        if (restarting) {
10649            return;
10650        }
10651
10652        if (!app.persistent || app.isolated) {
10653            if (DEBUG_PROCESSES) Slog.v(TAG,
10654                    "Removing non-persistent process during cleanup: " + app);
10655            mProcessNames.remove(app.processName, app.uid);
10656            mIsolatedProcesses.remove(app.uid);
10657            if (mHeavyWeightProcess == app) {
10658                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10659                        mHeavyWeightProcess.userId, 0));
10660                mHeavyWeightProcess = null;
10661            }
10662        } else if (!app.removed) {
10663            // This app is persistent, so we need to keep its record around.
10664            // If it is not already on the pending app list, add it there
10665            // and start a new process for it.
10666            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10667                mPersistentStartingProcesses.add(app);
10668                restart = true;
10669            }
10670        }
10671        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10672                "Clean-up removing on hold: " + app);
10673        mProcessesOnHold.remove(app);
10674
10675        if (app == mHomeProcess) {
10676            mHomeProcess = null;
10677        }
10678        if (app == mPreviousProcess) {
10679            mPreviousProcess = null;
10680        }
10681
10682        if (restart && !app.isolated) {
10683            // We have components that still need to be running in the
10684            // process, so re-launch it.
10685            mProcessNames.put(app.processName, app.uid, app);
10686            startProcessLocked(app, "restart", app.processName);
10687        } else if (app.pid > 0 && app.pid != MY_PID) {
10688            // Goodbye!
10689            synchronized (mPidsSelfLocked) {
10690                mPidsSelfLocked.remove(app.pid);
10691                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10692            }
10693            app.setPid(0);
10694        }
10695    }
10696
10697    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10698        // Look through the content providers we are waiting to have launched,
10699        // and if any run in this process then either schedule a restart of
10700        // the process or kill the client waiting for it if this process has
10701        // gone bad.
10702        int NL = mLaunchingProviders.size();
10703        boolean restart = false;
10704        for (int i=0; i<NL; i++) {
10705            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10706            if (cpr.launchingApp == app) {
10707                if (!alwaysBad && !app.bad) {
10708                    restart = true;
10709                } else {
10710                    removeDyingProviderLocked(app, cpr, true);
10711                    // cpr should have been removed from mLaunchingProviders
10712                    NL = mLaunchingProviders.size();
10713                    i--;
10714                }
10715            }
10716        }
10717        return restart;
10718    }
10719
10720    // =========================================================
10721    // SERVICES
10722    // =========================================================
10723
10724    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10725            int flags) {
10726        enforceNotIsolatedCaller("getServices");
10727        synchronized (this) {
10728            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10729        }
10730    }
10731
10732    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10733        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10734        synchronized (this) {
10735            return mServices.getRunningServiceControlPanelLocked(name);
10736        }
10737    }
10738
10739    public ComponentName startService(IApplicationThread caller, Intent service,
10740            String resolvedType, int userId) {
10741        enforceNotIsolatedCaller("startService");
10742        // Refuse possible leaked file descriptors
10743        if (service != null && service.hasFileDescriptors() == true) {
10744            throw new IllegalArgumentException("File descriptors passed in Intent");
10745        }
10746
10747        if (DEBUG_SERVICE)
10748            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10749        synchronized(this) {
10750            final int callingPid = Binder.getCallingPid();
10751            final int callingUid = Binder.getCallingUid();
10752            checkValidCaller(callingUid, userId);
10753            final long origId = Binder.clearCallingIdentity();
10754            ComponentName res = mServices.startServiceLocked(caller, service,
10755                    resolvedType, callingPid, callingUid, userId);
10756            Binder.restoreCallingIdentity(origId);
10757            return res;
10758        }
10759    }
10760
10761    ComponentName startServiceInPackage(int uid,
10762            Intent service, String resolvedType, int userId) {
10763        synchronized(this) {
10764            if (DEBUG_SERVICE)
10765                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10766            final long origId = Binder.clearCallingIdentity();
10767            ComponentName res = mServices.startServiceLocked(null, service,
10768                    resolvedType, -1, uid, userId);
10769            Binder.restoreCallingIdentity(origId);
10770            return res;
10771        }
10772    }
10773
10774    public int stopService(IApplicationThread caller, Intent service,
10775            String resolvedType, int userId) {
10776        enforceNotIsolatedCaller("stopService");
10777        // Refuse possible leaked file descriptors
10778        if (service != null && service.hasFileDescriptors() == true) {
10779            throw new IllegalArgumentException("File descriptors passed in Intent");
10780        }
10781
10782        checkValidCaller(Binder.getCallingUid(), userId);
10783
10784        synchronized(this) {
10785            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10786        }
10787    }
10788
10789    public IBinder peekService(Intent service, String resolvedType) {
10790        enforceNotIsolatedCaller("peekService");
10791        // Refuse possible leaked file descriptors
10792        if (service != null && service.hasFileDescriptors() == true) {
10793            throw new IllegalArgumentException("File descriptors passed in Intent");
10794        }
10795        synchronized(this) {
10796            return mServices.peekServiceLocked(service, resolvedType);
10797        }
10798    }
10799
10800    public boolean stopServiceToken(ComponentName className, IBinder token,
10801            int startId) {
10802        synchronized(this) {
10803            return mServices.stopServiceTokenLocked(className, token, startId);
10804        }
10805    }
10806
10807    public void setServiceForeground(ComponentName className, IBinder token,
10808            int id, Notification notification, boolean removeNotification) {
10809        synchronized(this) {
10810            mServices.setServiceForegroundLocked(className, token, id, notification,
10811                    removeNotification);
10812        }
10813    }
10814
10815    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
10816            boolean requireFull, String name, String callerPackage) {
10817        synchronized(this) {
10818            return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll,
10819                    requireFull, name, callerPackage);
10820        }
10821    }
10822
10823    int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll,
10824            boolean requireFull, String name, String callerPackage) {
10825        final int callingUserId = UserHandle.getUserId(callingUid);
10826        if (callingUserId != userId) {
10827            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10828                if ((requireFull || checkComponentPermission(
10829                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10830                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
10831                        && checkComponentPermission(
10832                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10833                                callingPid, callingUid, -1, true)
10834                                != PackageManager.PERMISSION_GRANTED) {
10835                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
10836                        // In this case, they would like to just execute as their
10837                        // owner user instead of failing.
10838                        userId = callingUserId;
10839                    } else {
10840                        StringBuilder builder = new StringBuilder(128);
10841                        builder.append("Permission Denial: ");
10842                        builder.append(name);
10843                        if (callerPackage != null) {
10844                            builder.append(" from ");
10845                            builder.append(callerPackage);
10846                        }
10847                        builder.append(" asks to run as user ");
10848                        builder.append(userId);
10849                        builder.append(" but is calling from user ");
10850                        builder.append(UserHandle.getUserId(callingUid));
10851                        builder.append("; this requires ");
10852                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
10853                        if (!requireFull) {
10854                            builder.append(" or ");
10855                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
10856                        }
10857                        String msg = builder.toString();
10858                        Slog.w(TAG, msg);
10859                        throw new SecurityException(msg);
10860                    }
10861                }
10862            }
10863            if (userId == UserHandle.USER_CURRENT
10864                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
10865                userId = mCurrentUserId;
10866            }
10867            if (!allowAll && userId < 0) {
10868                throw new IllegalArgumentException(
10869                        "Call does not support special user #" + userId);
10870            }
10871        }
10872        return userId;
10873    }
10874
10875    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10876            String className, int flags) {
10877        boolean result = false;
10878        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10879            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10880                if (ActivityManager.checkUidPermission(
10881                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10882                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10883                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10884                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10885                            + " requests FLAG_SINGLE_USER, but app does not hold "
10886                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10887                    Slog.w(TAG, msg);
10888                    throw new SecurityException(msg);
10889                }
10890                result = true;
10891            }
10892        } else if (componentProcessName == aInfo.packageName) {
10893            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10894        } else if ("system".equals(componentProcessName)) {
10895            result = true;
10896        }
10897        if (DEBUG_MU) {
10898            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10899                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10900        }
10901        return result;
10902    }
10903
10904    public int bindService(IApplicationThread caller, IBinder token,
10905            Intent service, String resolvedType,
10906            IServiceConnection connection, int flags, int userId) {
10907        enforceNotIsolatedCaller("bindService");
10908        // Refuse possible leaked file descriptors
10909        if (service != null && service.hasFileDescriptors() == true) {
10910            throw new IllegalArgumentException("File descriptors passed in Intent");
10911        }
10912
10913        synchronized(this) {
10914            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10915                    connection, flags, userId);
10916        }
10917    }
10918
10919    public boolean unbindService(IServiceConnection connection) {
10920        synchronized (this) {
10921            return mServices.unbindServiceLocked(connection);
10922        }
10923    }
10924
10925    public void publishService(IBinder token, Intent intent, IBinder service) {
10926        // Refuse possible leaked file descriptors
10927        if (intent != null && intent.hasFileDescriptors() == true) {
10928            throw new IllegalArgumentException("File descriptors passed in Intent");
10929        }
10930
10931        synchronized(this) {
10932            if (!(token instanceof ServiceRecord)) {
10933                throw new IllegalArgumentException("Invalid service token");
10934            }
10935            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
10936        }
10937    }
10938
10939    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10940        // Refuse possible leaked file descriptors
10941        if (intent != null && intent.hasFileDescriptors() == true) {
10942            throw new IllegalArgumentException("File descriptors passed in Intent");
10943        }
10944
10945        synchronized(this) {
10946            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
10947        }
10948    }
10949
10950    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10951        synchronized(this) {
10952            if (!(token instanceof ServiceRecord)) {
10953                throw new IllegalArgumentException("Invalid service token");
10954            }
10955            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
10956        }
10957    }
10958
10959    // =========================================================
10960    // BACKUP AND RESTORE
10961    // =========================================================
10962
10963    // Cause the target app to be launched if necessary and its backup agent
10964    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10965    // activity manager to announce its creation.
10966    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10967        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10968        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10969
10970        synchronized(this) {
10971            // !!! TODO: currently no check here that we're already bound
10972            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10973            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10974            synchronized (stats) {
10975                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10976            }
10977
10978            // Backup agent is now in use, its package can't be stopped.
10979            try {
10980                AppGlobals.getPackageManager().setPackageStoppedState(
10981                        app.packageName, false, UserHandle.getUserId(app.uid));
10982            } catch (RemoteException e) {
10983            } catch (IllegalArgumentException e) {
10984                Slog.w(TAG, "Failed trying to unstop package "
10985                        + app.packageName + ": " + e);
10986            }
10987
10988            BackupRecord r = new BackupRecord(ss, app, backupMode);
10989            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10990                    ? new ComponentName(app.packageName, app.backupAgentName)
10991                    : new ComponentName("android", "FullBackupAgent");
10992            // startProcessLocked() returns existing proc's record if it's already running
10993            ProcessRecord proc = startProcessLocked(app.processName, app,
10994                    false, 0, "backup", hostingName, false, false);
10995            if (proc == null) {
10996                Slog.e(TAG, "Unable to start backup agent process " + r);
10997                return false;
10998            }
10999
11000            r.app = proc;
11001            mBackupTarget = r;
11002            mBackupAppName = app.packageName;
11003
11004            // Try not to kill the process during backup
11005            updateOomAdjLocked(proc);
11006
11007            // If the process is already attached, schedule the creation of the backup agent now.
11008            // If it is not yet live, this will be done when it attaches to the framework.
11009            if (proc.thread != null) {
11010                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11011                try {
11012                    proc.thread.scheduleCreateBackupAgent(app,
11013                            compatibilityInfoForPackageLocked(app), backupMode);
11014                } catch (RemoteException e) {
11015                    // Will time out on the backup manager side
11016                }
11017            } else {
11018                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11019            }
11020            // Invariants: at this point, the target app process exists and the application
11021            // is either already running or in the process of coming up.  mBackupTarget and
11022            // mBackupAppName describe the app, so that when it binds back to the AM we
11023            // know that it's scheduled for a backup-agent operation.
11024        }
11025
11026        return true;
11027    }
11028
11029    // A backup agent has just come up
11030    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11031        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11032                + " = " + agent);
11033
11034        synchronized(this) {
11035            if (!agentPackageName.equals(mBackupAppName)) {
11036                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11037                return;
11038            }
11039        }
11040
11041        long oldIdent = Binder.clearCallingIdentity();
11042        try {
11043            IBackupManager bm = IBackupManager.Stub.asInterface(
11044                    ServiceManager.getService(Context.BACKUP_SERVICE));
11045            bm.agentConnected(agentPackageName, agent);
11046        } catch (RemoteException e) {
11047            // can't happen; the backup manager service is local
11048        } catch (Exception e) {
11049            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11050            e.printStackTrace();
11051        } finally {
11052            Binder.restoreCallingIdentity(oldIdent);
11053        }
11054    }
11055
11056    // done with this agent
11057    public void unbindBackupAgent(ApplicationInfo appInfo) {
11058        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11059        if (appInfo == null) {
11060            Slog.w(TAG, "unbind backup agent for null app");
11061            return;
11062        }
11063
11064        synchronized(this) {
11065            if (mBackupAppName == null) {
11066                Slog.w(TAG, "Unbinding backup agent with no active backup");
11067                return;
11068            }
11069
11070            if (!mBackupAppName.equals(appInfo.packageName)) {
11071                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11072                return;
11073            }
11074
11075            ProcessRecord proc = mBackupTarget.app;
11076            mBackupTarget = null;
11077            mBackupAppName = null;
11078
11079            // Not backing this app up any more; reset its OOM adjustment
11080            updateOomAdjLocked(proc);
11081
11082            // If the app crashed during backup, 'thread' will be null here
11083            if (proc.thread != null) {
11084                try {
11085                    proc.thread.scheduleDestroyBackupAgent(appInfo,
11086                            compatibilityInfoForPackageLocked(appInfo));
11087                } catch (Exception e) {
11088                    Slog.e(TAG, "Exception when unbinding backup agent:");
11089                    e.printStackTrace();
11090                }
11091            }
11092        }
11093    }
11094    // =========================================================
11095    // BROADCASTS
11096    // =========================================================
11097
11098    private final List getStickiesLocked(String action, IntentFilter filter,
11099            List cur, int userId) {
11100        final ContentResolver resolver = mContext.getContentResolver();
11101        HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11102        if (stickies == null) {
11103            return cur;
11104        }
11105        final ArrayList<Intent> list = stickies.get(action);
11106        if (list == null) {
11107            return cur;
11108        }
11109        int N = list.size();
11110        for (int i=0; i<N; i++) {
11111            Intent intent = list.get(i);
11112            if (filter.match(resolver, intent, true, TAG) >= 0) {
11113                if (cur == null) {
11114                    cur = new ArrayList<Intent>();
11115                }
11116                cur.add(intent);
11117            }
11118        }
11119        return cur;
11120    }
11121
11122    boolean isPendingBroadcastProcessLocked(int pid) {
11123        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11124                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11125    }
11126
11127    void skipPendingBroadcastLocked(int pid) {
11128            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11129            for (BroadcastQueue queue : mBroadcastQueues) {
11130                queue.skipPendingBroadcastLocked(pid);
11131            }
11132    }
11133
11134    // The app just attached; send any pending broadcasts that it should receive
11135    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11136        boolean didSomething = false;
11137        for (BroadcastQueue queue : mBroadcastQueues) {
11138            didSomething |= queue.sendPendingBroadcastsLocked(app);
11139        }
11140        return didSomething;
11141    }
11142
11143    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11144            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11145        enforceNotIsolatedCaller("registerReceiver");
11146        int callingUid;
11147        int callingPid;
11148        synchronized(this) {
11149            ProcessRecord callerApp = null;
11150            if (caller != null) {
11151                callerApp = getRecordForAppLocked(caller);
11152                if (callerApp == null) {
11153                    throw new SecurityException(
11154                            "Unable to find app for caller " + caller
11155                            + " (pid=" + Binder.getCallingPid()
11156                            + ") when registering receiver " + receiver);
11157                }
11158                if (callerApp.info.uid != Process.SYSTEM_UID &&
11159                        !callerApp.pkgList.contains(callerPackage)) {
11160                    throw new SecurityException("Given caller package " + callerPackage
11161                            + " is not running in process " + callerApp);
11162                }
11163                callingUid = callerApp.info.uid;
11164                callingPid = callerApp.pid;
11165            } else {
11166                callerPackage = null;
11167                callingUid = Binder.getCallingUid();
11168                callingPid = Binder.getCallingPid();
11169            }
11170
11171            userId = this.handleIncomingUserLocked(callingPid, callingUid, userId,
11172                    true, true, "registerReceiver", callerPackage);
11173
11174            List allSticky = null;
11175
11176            // Look for any matching sticky broadcasts...
11177            Iterator actions = filter.actionsIterator();
11178            if (actions != null) {
11179                while (actions.hasNext()) {
11180                    String action = (String)actions.next();
11181                    allSticky = getStickiesLocked(action, filter, allSticky,
11182                            UserHandle.USER_ALL);
11183                    allSticky = getStickiesLocked(action, filter, allSticky,
11184                            UserHandle.getUserId(callingUid));
11185                }
11186            } else {
11187                allSticky = getStickiesLocked(null, filter, allSticky,
11188                        UserHandle.USER_ALL);
11189                allSticky = getStickiesLocked(null, filter, allSticky,
11190                        UserHandle.getUserId(callingUid));
11191            }
11192
11193            // The first sticky in the list is returned directly back to
11194            // the client.
11195            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11196
11197            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11198                    + ": " + sticky);
11199
11200            if (receiver == null) {
11201                return sticky;
11202            }
11203
11204            ReceiverList rl
11205                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11206            if (rl == null) {
11207                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11208                        userId, receiver);
11209                if (rl.app != null) {
11210                    rl.app.receivers.add(rl);
11211                } else {
11212                    try {
11213                        receiver.asBinder().linkToDeath(rl, 0);
11214                    } catch (RemoteException e) {
11215                        return sticky;
11216                    }
11217                    rl.linkedToDeath = true;
11218                }
11219                mRegisteredReceivers.put(receiver.asBinder(), rl);
11220            } else if (rl.uid != callingUid) {
11221                throw new IllegalArgumentException(
11222                        "Receiver requested to register for uid " + callingUid
11223                        + " was previously registered for uid " + rl.uid);
11224            } else if (rl.pid != callingPid) {
11225                throw new IllegalArgumentException(
11226                        "Receiver requested to register for pid " + callingPid
11227                        + " was previously registered for pid " + rl.pid);
11228            } else if (rl.userId != userId) {
11229                throw new IllegalArgumentException(
11230                        "Receiver requested to register for user " + userId
11231                        + " was previously registered for user " + rl.userId);
11232            }
11233            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11234                    permission, callingUid, userId);
11235            rl.add(bf);
11236            if (!bf.debugCheck()) {
11237                Slog.w(TAG, "==> For Dynamic broadast");
11238            }
11239            mReceiverResolver.addFilter(bf);
11240
11241            // Enqueue broadcasts for all existing stickies that match
11242            // this filter.
11243            if (allSticky != null) {
11244                ArrayList receivers = new ArrayList();
11245                receivers.add(bf);
11246
11247                int N = allSticky.size();
11248                for (int i=0; i<N; i++) {
11249                    Intent intent = (Intent)allSticky.get(i);
11250                    BroadcastQueue queue = broadcastQueueForIntent(intent);
11251                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11252                            null, -1, -1, null, receivers, null, 0, null, null,
11253                            false, true, true, -1);
11254                    queue.enqueueParallelBroadcastLocked(r);
11255                    queue.scheduleBroadcastsLocked();
11256                }
11257            }
11258
11259            return sticky;
11260        }
11261    }
11262
11263    public void unregisterReceiver(IIntentReceiver receiver) {
11264        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11265
11266        final long origId = Binder.clearCallingIdentity();
11267        try {
11268            boolean doTrim = false;
11269
11270            synchronized(this) {
11271                ReceiverList rl
11272                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11273                if (rl != null) {
11274                    if (rl.curBroadcast != null) {
11275                        BroadcastRecord r = rl.curBroadcast;
11276                        final boolean doNext = finishReceiverLocked(
11277                                receiver.asBinder(), r.resultCode, r.resultData,
11278                                r.resultExtras, r.resultAbort, true);
11279                        if (doNext) {
11280                            doTrim = true;
11281                            r.queue.processNextBroadcast(false);
11282                        }
11283                    }
11284
11285                    if (rl.app != null) {
11286                        rl.app.receivers.remove(rl);
11287                    }
11288                    removeReceiverLocked(rl);
11289                    if (rl.linkedToDeath) {
11290                        rl.linkedToDeath = false;
11291                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11292                    }
11293                }
11294            }
11295
11296            // If we actually concluded any broadcasts, we might now be able
11297            // to trim the recipients' apps from our working set
11298            if (doTrim) {
11299                trimApplications();
11300                return;
11301            }
11302
11303        } finally {
11304            Binder.restoreCallingIdentity(origId);
11305        }
11306    }
11307
11308    void removeReceiverLocked(ReceiverList rl) {
11309        mRegisteredReceivers.remove(rl.receiver.asBinder());
11310        int N = rl.size();
11311        for (int i=0; i<N; i++) {
11312            mReceiverResolver.removeFilter(rl.get(i));
11313        }
11314    }
11315
11316    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11317        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11318            ProcessRecord r = mLruProcesses.get(i);
11319            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11320                try {
11321                    r.thread.dispatchPackageBroadcast(cmd, packages);
11322                } catch (RemoteException ex) {
11323                }
11324            }
11325        }
11326    }
11327
11328    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11329            int[] users) {
11330        List<ResolveInfo> receivers = null;
11331        try {
11332            HashSet<ComponentName> singleUserReceivers = null;
11333            boolean scannedFirstReceivers = false;
11334            for (int user : users) {
11335                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11336                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11337                if (newReceivers != null && newReceivers.size() == 0) {
11338                    newReceivers = null;
11339                }
11340                if (receivers == null) {
11341                    receivers = newReceivers;
11342                } else if (newReceivers != null) {
11343                    // We need to concatenate the additional receivers
11344                    // found with what we have do far.  This would be easy,
11345                    // but we also need to de-dup any receivers that are
11346                    // singleUser.
11347                    if (!scannedFirstReceivers) {
11348                        // Collect any single user receivers we had already retrieved.
11349                        scannedFirstReceivers = true;
11350                        for (int i=0; i<receivers.size(); i++) {
11351                            ResolveInfo ri = receivers.get(i);
11352                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11353                                ComponentName cn = new ComponentName(
11354                                        ri.activityInfo.packageName, ri.activityInfo.name);
11355                                if (singleUserReceivers == null) {
11356                                    singleUserReceivers = new HashSet<ComponentName>();
11357                                }
11358                                singleUserReceivers.add(cn);
11359                            }
11360                        }
11361                    }
11362                    // Add the new results to the existing results, tracking
11363                    // and de-dupping single user receivers.
11364                    for (int i=0; i<newReceivers.size(); i++) {
11365                        ResolveInfo ri = receivers.get(i);
11366                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11367                            ComponentName cn = new ComponentName(
11368                                    ri.activityInfo.packageName, ri.activityInfo.name);
11369                            if (singleUserReceivers == null) {
11370                                singleUserReceivers = new HashSet<ComponentName>();
11371                            }
11372                            if (!singleUserReceivers.contains(cn)) {
11373                                singleUserReceivers.add(cn);
11374                                receivers.add(ri);
11375                            }
11376                        } else {
11377                            receivers.add(ri);
11378                        }
11379                    }
11380                }
11381            }
11382        } catch (RemoteException ex) {
11383            // pm is in same process, this will never happen.
11384        }
11385        return receivers;
11386    }
11387
11388    private final int broadcastIntentLocked(ProcessRecord callerApp,
11389            String callerPackage, Intent intent, String resolvedType,
11390            IIntentReceiver resultTo, int resultCode, String resultData,
11391            Bundle map, String requiredPermission,
11392            boolean ordered, boolean sticky, int callingPid, int callingUid,
11393            int userId) {
11394        intent = new Intent(intent);
11395
11396        // By default broadcasts do not go to stopped apps.
11397        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11398
11399        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11400            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11401            + " ordered=" + ordered + " userid=" + userId);
11402        if ((resultTo != null) && !ordered) {
11403            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11404        }
11405
11406        userId = handleIncomingUserLocked(callingPid, callingUid, userId,
11407                true, false, "broadcast", callerPackage);
11408
11409        // Make sure that the user who is receiving this broadcast is started
11410        // If not, we will just skip it.
11411        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11412            Slog.w(TAG, "Skipping broadcast of " + intent
11413                    + ": user " + userId + " is stopped");
11414            return ActivityManager.BROADCAST_SUCCESS;
11415        }
11416
11417        /*
11418         * Prevent non-system code (defined here to be non-persistent
11419         * processes) from sending protected broadcasts.
11420         */
11421        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11422            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11423            callingUid == 0) {
11424            // Always okay.
11425        } else if (callerApp == null || !callerApp.persistent) {
11426            try {
11427                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11428                        intent.getAction())) {
11429                    String msg = "Permission Denial: not allowed to send broadcast "
11430                            + intent.getAction() + " from pid="
11431                            + callingPid + ", uid=" + callingUid;
11432                    Slog.w(TAG, msg);
11433                    throw new SecurityException(msg);
11434                }
11435            } catch (RemoteException e) {
11436                Slog.w(TAG, "Remote exception", e);
11437                return ActivityManager.BROADCAST_SUCCESS;
11438            }
11439        }
11440
11441        // Handle special intents: if this broadcast is from the package
11442        // manager about a package being removed, we need to remove all of
11443        // its activities from the history stack.
11444        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11445                intent.getAction());
11446        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11447                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11448                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11449                || uidRemoved) {
11450            if (checkComponentPermission(
11451                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11452                    callingPid, callingUid, -1, true)
11453                    == PackageManager.PERMISSION_GRANTED) {
11454                if (uidRemoved) {
11455                    final Bundle intentExtras = intent.getExtras();
11456                    final int uid = intentExtras != null
11457                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11458                    if (uid >= 0) {
11459                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11460                        synchronized (bs) {
11461                            bs.removeUidStatsLocked(uid);
11462                        }
11463                    }
11464                } else {
11465                    // If resources are unavailable just force stop all
11466                    // those packages and flush the attribute cache as well.
11467                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11468                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11469                        if (list != null && (list.length > 0)) {
11470                            for (String pkg : list) {
11471                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11472                            }
11473                            sendPackageBroadcastLocked(
11474                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11475                        }
11476                    } else {
11477                        Uri data = intent.getData();
11478                        String ssp;
11479                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11480                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11481                                forceStopPackageLocked(ssp,
11482                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11483                                        false, userId);
11484                            }
11485                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11486                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11487                                        new String[] {ssp}, userId);
11488                            }
11489                        }
11490                    }
11491                }
11492            } else {
11493                String msg = "Permission Denial: " + intent.getAction()
11494                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11495                        + ", uid=" + callingUid + ")"
11496                        + " requires "
11497                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11498                Slog.w(TAG, msg);
11499                throw new SecurityException(msg);
11500            }
11501
11502        // Special case for adding a package: by default turn on compatibility
11503        // mode.
11504        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11505            Uri data = intent.getData();
11506            String ssp;
11507            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11508                mCompatModePackages.handlePackageAddedLocked(ssp,
11509                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11510            }
11511        }
11512
11513        /*
11514         * If this is the time zone changed action, queue up a message that will reset the timezone
11515         * of all currently running processes. This message will get queued up before the broadcast
11516         * happens.
11517         */
11518        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11519            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11520        }
11521
11522        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11523            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11524        }
11525
11526        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11527            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11528            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11529        }
11530
11531        // Add to the sticky list if requested.
11532        if (sticky) {
11533            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11534                    callingPid, callingUid)
11535                    != PackageManager.PERMISSION_GRANTED) {
11536                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11537                        + callingPid + ", uid=" + callingUid
11538                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11539                Slog.w(TAG, msg);
11540                throw new SecurityException(msg);
11541            }
11542            if (requiredPermission != null) {
11543                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11544                        + " and enforce permission " + requiredPermission);
11545                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11546            }
11547            if (intent.getComponent() != null) {
11548                throw new SecurityException(
11549                        "Sticky broadcasts can't target a specific component");
11550            }
11551            // We use userId directly here, since the "all" target is maintained
11552            // as a separate set of sticky broadcasts.
11553            if (userId != UserHandle.USER_ALL) {
11554                // But first, if this is not a broadcast to all users, then
11555                // make sure it doesn't conflict with an existing broadcast to
11556                // all users.
11557                HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11558                        UserHandle.USER_ALL);
11559                if (stickies != null) {
11560                    ArrayList<Intent> list = stickies.get(intent.getAction());
11561                    if (list != null) {
11562                        int N = list.size();
11563                        int i;
11564                        for (i=0; i<N; i++) {
11565                            if (intent.filterEquals(list.get(i))) {
11566                                throw new IllegalArgumentException(
11567                                        "Sticky broadcast " + intent + " for user "
11568                                        + userId + " conflicts with existing global broadcast");
11569                            }
11570                        }
11571                    }
11572                }
11573            }
11574            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11575            if (stickies == null) {
11576                stickies = new HashMap<String, ArrayList<Intent>>();
11577                mStickyBroadcasts.put(userId, stickies);
11578            }
11579            ArrayList<Intent> list = stickies.get(intent.getAction());
11580            if (list == null) {
11581                list = new ArrayList<Intent>();
11582                stickies.put(intent.getAction(), list);
11583            }
11584            int N = list.size();
11585            int i;
11586            for (i=0; i<N; i++) {
11587                if (intent.filterEquals(list.get(i))) {
11588                    // This sticky already exists, replace it.
11589                    list.set(i, new Intent(intent));
11590                    break;
11591                }
11592            }
11593            if (i >= N) {
11594                list.add(new Intent(intent));
11595            }
11596        }
11597
11598        int[] users;
11599        if (userId == UserHandle.USER_ALL) {
11600            // Caller wants broadcast to go to all started users.
11601            users = new int[mStartedUsers.size()];
11602            for (int i=0; i<mStartedUsers.size(); i++) {
11603                users[i] = mStartedUsers.keyAt(i);
11604            }
11605        } else {
11606            // Caller wants broadcast to go to one specific user.
11607            users = new int[] {userId};
11608        }
11609
11610        // Figure out who all will receive this broadcast.
11611        List receivers = null;
11612        List<BroadcastFilter> registeredReceivers = null;
11613        // Need to resolve the intent to interested receivers...
11614        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11615                 == 0) {
11616            receivers = collectReceiverComponents(intent, resolvedType, users);
11617        }
11618        if (intent.getComponent() == null) {
11619            registeredReceivers = mReceiverResolver.queryIntent(intent,
11620                    resolvedType, false, userId);
11621        }
11622
11623        final boolean replacePending =
11624                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11625
11626        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11627                + " replacePending=" + replacePending);
11628
11629        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11630        if (!ordered && NR > 0) {
11631            // If we are not serializing this broadcast, then send the
11632            // registered receivers separately so they don't wait for the
11633            // components to be launched.
11634            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11635            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11636                    callerPackage, callingPid, callingUid, requiredPermission,
11637                    registeredReceivers, resultTo, resultCode, resultData, map,
11638                    ordered, sticky, false, userId);
11639            if (DEBUG_BROADCAST) Slog.v(
11640                    TAG, "Enqueueing parallel broadcast " + r);
11641            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11642            if (!replaced) {
11643                queue.enqueueParallelBroadcastLocked(r);
11644                queue.scheduleBroadcastsLocked();
11645            }
11646            registeredReceivers = null;
11647            NR = 0;
11648        }
11649
11650        // Merge into one list.
11651        int ir = 0;
11652        if (receivers != null) {
11653            // A special case for PACKAGE_ADDED: do not allow the package
11654            // being added to see this broadcast.  This prevents them from
11655            // using this as a back door to get run as soon as they are
11656            // installed.  Maybe in the future we want to have a special install
11657            // broadcast or such for apps, but we'd like to deliberately make
11658            // this decision.
11659            String skipPackages[] = null;
11660            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11661                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11662                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11663                Uri data = intent.getData();
11664                if (data != null) {
11665                    String pkgName = data.getSchemeSpecificPart();
11666                    if (pkgName != null) {
11667                        skipPackages = new String[] { pkgName };
11668                    }
11669                }
11670            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11671                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11672            }
11673            if (skipPackages != null && (skipPackages.length > 0)) {
11674                for (String skipPackage : skipPackages) {
11675                    if (skipPackage != null) {
11676                        int NT = receivers.size();
11677                        for (int it=0; it<NT; it++) {
11678                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11679                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11680                                receivers.remove(it);
11681                                it--;
11682                                NT--;
11683                            }
11684                        }
11685                    }
11686                }
11687            }
11688
11689            int NT = receivers != null ? receivers.size() : 0;
11690            int it = 0;
11691            ResolveInfo curt = null;
11692            BroadcastFilter curr = null;
11693            while (it < NT && ir < NR) {
11694                if (curt == null) {
11695                    curt = (ResolveInfo)receivers.get(it);
11696                }
11697                if (curr == null) {
11698                    curr = registeredReceivers.get(ir);
11699                }
11700                if (curr.getPriority() >= curt.priority) {
11701                    // Insert this broadcast record into the final list.
11702                    receivers.add(it, curr);
11703                    ir++;
11704                    curr = null;
11705                    it++;
11706                    NT++;
11707                } else {
11708                    // Skip to the next ResolveInfo in the final list.
11709                    it++;
11710                    curt = null;
11711                }
11712            }
11713        }
11714        while (ir < NR) {
11715            if (receivers == null) {
11716                receivers = new ArrayList();
11717            }
11718            receivers.add(registeredReceivers.get(ir));
11719            ir++;
11720        }
11721
11722        if ((receivers != null && receivers.size() > 0)
11723                || resultTo != null) {
11724            BroadcastQueue queue = broadcastQueueForIntent(intent);
11725            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11726                    callerPackage, callingPid, callingUid, requiredPermission,
11727                    receivers, resultTo, resultCode, resultData, map, ordered,
11728                    sticky, false, userId);
11729            if (DEBUG_BROADCAST) Slog.v(
11730                    TAG, "Enqueueing ordered broadcast " + r
11731                    + ": prev had " + queue.mOrderedBroadcasts.size());
11732            if (DEBUG_BROADCAST) {
11733                int seq = r.intent.getIntExtra("seq", -1);
11734                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11735            }
11736            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11737            if (!replaced) {
11738                queue.enqueueOrderedBroadcastLocked(r);
11739                queue.scheduleBroadcastsLocked();
11740            }
11741        }
11742
11743        return ActivityManager.BROADCAST_SUCCESS;
11744    }
11745
11746    final Intent verifyBroadcastLocked(Intent intent) {
11747        // Refuse possible leaked file descriptors
11748        if (intent != null && intent.hasFileDescriptors() == true) {
11749            throw new IllegalArgumentException("File descriptors passed in Intent");
11750        }
11751
11752        int flags = intent.getFlags();
11753
11754        if (!mProcessesReady) {
11755            // if the caller really truly claims to know what they're doing, go
11756            // ahead and allow the broadcast without launching any receivers
11757            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11758                intent = new Intent(intent);
11759                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11760            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11761                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11762                        + " before boot completion");
11763                throw new IllegalStateException("Cannot broadcast before boot completed");
11764            }
11765        }
11766
11767        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11768            throw new IllegalArgumentException(
11769                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11770        }
11771
11772        return intent;
11773    }
11774
11775    public final int broadcastIntent(IApplicationThread caller,
11776            Intent intent, String resolvedType, IIntentReceiver resultTo,
11777            int resultCode, String resultData, Bundle map,
11778            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11779        enforceNotIsolatedCaller("broadcastIntent");
11780        synchronized(this) {
11781            intent = verifyBroadcastLocked(intent);
11782
11783            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11784            final int callingPid = Binder.getCallingPid();
11785            final int callingUid = Binder.getCallingUid();
11786            final long origId = Binder.clearCallingIdentity();
11787            int res = broadcastIntentLocked(callerApp,
11788                    callerApp != null ? callerApp.info.packageName : null,
11789                    intent, resolvedType, resultTo,
11790                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11791                    callingPid, callingUid, userId);
11792            Binder.restoreCallingIdentity(origId);
11793            return res;
11794        }
11795    }
11796
11797    int broadcastIntentInPackage(String packageName, int uid,
11798            Intent intent, String resolvedType, IIntentReceiver resultTo,
11799            int resultCode, String resultData, Bundle map,
11800            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11801        synchronized(this) {
11802            intent = verifyBroadcastLocked(intent);
11803
11804            final long origId = Binder.clearCallingIdentity();
11805            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11806                    resultTo, resultCode, resultData, map, requiredPermission,
11807                    serialized, sticky, -1, uid, userId);
11808            Binder.restoreCallingIdentity(origId);
11809            return res;
11810        }
11811    }
11812
11813    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11814        // Refuse possible leaked file descriptors
11815        if (intent != null && intent.hasFileDescriptors() == true) {
11816            throw new IllegalArgumentException("File descriptors passed in Intent");
11817        }
11818
11819        userId = handleIncomingUserLocked(Binder.getCallingPid(),
11820                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
11821
11822        synchronized(this) {
11823            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11824                    != PackageManager.PERMISSION_GRANTED) {
11825                String msg = "Permission Denial: unbroadcastIntent() from pid="
11826                        + Binder.getCallingPid()
11827                        + ", uid=" + Binder.getCallingUid()
11828                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11829                Slog.w(TAG, msg);
11830                throw new SecurityException(msg);
11831            }
11832            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11833            if (stickies != null) {
11834                ArrayList<Intent> list = stickies.get(intent.getAction());
11835                if (list != null) {
11836                    int N = list.size();
11837                    int i;
11838                    for (i=0; i<N; i++) {
11839                        if (intent.filterEquals(list.get(i))) {
11840                            list.remove(i);
11841                            break;
11842                        }
11843                    }
11844                    if (list.size() <= 0) {
11845                        stickies.remove(intent.getAction());
11846                    }
11847                }
11848                if (stickies.size() <= 0) {
11849                    mStickyBroadcasts.remove(userId);
11850                }
11851            }
11852        }
11853    }
11854
11855    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11856            String resultData, Bundle resultExtras, boolean resultAbort,
11857            boolean explicit) {
11858        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11859        if (r == null) {
11860            Slog.w(TAG, "finishReceiver called but not found on queue");
11861            return false;
11862        }
11863
11864        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11865                explicit);
11866    }
11867
11868    public void finishReceiver(IBinder who, int resultCode, String resultData,
11869            Bundle resultExtras, boolean resultAbort) {
11870        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11871
11872        // Refuse possible leaked file descriptors
11873        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11874            throw new IllegalArgumentException("File descriptors passed in Bundle");
11875        }
11876
11877        final long origId = Binder.clearCallingIdentity();
11878        try {
11879            boolean doNext = false;
11880            BroadcastRecord r = null;
11881
11882            synchronized(this) {
11883                r = broadcastRecordForReceiverLocked(who);
11884                if (r != null) {
11885                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11886                        resultData, resultExtras, resultAbort, true);
11887                }
11888            }
11889
11890            if (doNext) {
11891                r.queue.processNextBroadcast(false);
11892            }
11893            trimApplications();
11894        } finally {
11895            Binder.restoreCallingIdentity(origId);
11896        }
11897    }
11898
11899    // =========================================================
11900    // INSTRUMENTATION
11901    // =========================================================
11902
11903    public boolean startInstrumentation(ComponentName className,
11904            String profileFile, int flags, Bundle arguments,
11905            IInstrumentationWatcher watcher, int userId) {
11906        enforceNotIsolatedCaller("startInstrumentation");
11907        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
11908                userId, false, true, "startInstrumentation", null);
11909        // Refuse possible leaked file descriptors
11910        if (arguments != null && arguments.hasFileDescriptors()) {
11911            throw new IllegalArgumentException("File descriptors passed in Bundle");
11912        }
11913
11914        synchronized(this) {
11915            InstrumentationInfo ii = null;
11916            ApplicationInfo ai = null;
11917            try {
11918                ii = mContext.getPackageManager().getInstrumentationInfo(
11919                    className, STOCK_PM_FLAGS);
11920                ai = AppGlobals.getPackageManager().getApplicationInfo(
11921                        ii.targetPackage, STOCK_PM_FLAGS, userId);
11922            } catch (PackageManager.NameNotFoundException e) {
11923            } catch (RemoteException e) {
11924            }
11925            if (ii == null) {
11926                reportStartInstrumentationFailure(watcher, className,
11927                        "Unable to find instrumentation info for: " + className);
11928                return false;
11929            }
11930            if (ai == null) {
11931                reportStartInstrumentationFailure(watcher, className,
11932                        "Unable to find instrumentation target package: " + ii.targetPackage);
11933                return false;
11934            }
11935
11936            int match = mContext.getPackageManager().checkSignatures(
11937                    ii.targetPackage, ii.packageName);
11938            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11939                String msg = "Permission Denial: starting instrumentation "
11940                        + className + " from pid="
11941                        + Binder.getCallingPid()
11942                        + ", uid=" + Binder.getCallingPid()
11943                        + " not allowed because package " + ii.packageName
11944                        + " does not have a signature matching the target "
11945                        + ii.targetPackage;
11946                reportStartInstrumentationFailure(watcher, className, msg);
11947                throw new SecurityException(msg);
11948            }
11949
11950            final long origId = Binder.clearCallingIdentity();
11951            // Instrumentation can kill and relaunch even persistent processes
11952            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
11953            ProcessRecord app = addAppLocked(ai, false);
11954            app.instrumentationClass = className;
11955            app.instrumentationInfo = ai;
11956            app.instrumentationProfileFile = profileFile;
11957            app.instrumentationArguments = arguments;
11958            app.instrumentationWatcher = watcher;
11959            app.instrumentationResultClass = className;
11960            Binder.restoreCallingIdentity(origId);
11961        }
11962
11963        return true;
11964    }
11965
11966    /**
11967     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11968     * error to the logs, but if somebody is watching, send the report there too.  This enables
11969     * the "am" command to report errors with more information.
11970     *
11971     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11972     * @param cn The component name of the instrumentation.
11973     * @param report The error report.
11974     */
11975    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11976            ComponentName cn, String report) {
11977        Slog.w(TAG, report);
11978        try {
11979            if (watcher != null) {
11980                Bundle results = new Bundle();
11981                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11982                results.putString("Error", report);
11983                watcher.instrumentationStatus(cn, -1, results);
11984            }
11985        } catch (RemoteException e) {
11986            Slog.w(TAG, e);
11987        }
11988    }
11989
11990    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11991        if (app.instrumentationWatcher != null) {
11992            try {
11993                // NOTE:  IInstrumentationWatcher *must* be oneway here
11994                app.instrumentationWatcher.instrumentationFinished(
11995                    app.instrumentationClass,
11996                    resultCode,
11997                    results);
11998            } catch (RemoteException e) {
11999            }
12000        }
12001        app.instrumentationWatcher = null;
12002        app.instrumentationClass = null;
12003        app.instrumentationInfo = null;
12004        app.instrumentationProfileFile = null;
12005        app.instrumentationArguments = null;
12006
12007        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
12008    }
12009
12010    public void finishInstrumentation(IApplicationThread target,
12011            int resultCode, Bundle results) {
12012        int userId = UserHandle.getCallingUserId();
12013        // Refuse possible leaked file descriptors
12014        if (results != null && results.hasFileDescriptors()) {
12015            throw new IllegalArgumentException("File descriptors passed in Intent");
12016        }
12017
12018        synchronized(this) {
12019            ProcessRecord app = getRecordForAppLocked(target);
12020            if (app == null) {
12021                Slog.w(TAG, "finishInstrumentation: no app for " + target);
12022                return;
12023            }
12024            final long origId = Binder.clearCallingIdentity();
12025            finishInstrumentationLocked(app, resultCode, results);
12026            Binder.restoreCallingIdentity(origId);
12027        }
12028    }
12029
12030    // =========================================================
12031    // CONFIGURATION
12032    // =========================================================
12033
12034    public ConfigurationInfo getDeviceConfigurationInfo() {
12035        ConfigurationInfo config = new ConfigurationInfo();
12036        synchronized (this) {
12037            config.reqTouchScreen = mConfiguration.touchscreen;
12038            config.reqKeyboardType = mConfiguration.keyboard;
12039            config.reqNavigation = mConfiguration.navigation;
12040            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12041                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12042                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12043            }
12044            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12045                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12046                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12047            }
12048            config.reqGlEsVersion = GL_ES_VERSION;
12049        }
12050        return config;
12051    }
12052
12053    public Configuration getConfiguration() {
12054        Configuration ci;
12055        synchronized(this) {
12056            ci = new Configuration(mConfiguration);
12057        }
12058        return ci;
12059    }
12060
12061    public void updatePersistentConfiguration(Configuration values) {
12062        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12063                "updateConfiguration()");
12064        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12065                "updateConfiguration()");
12066        if (values == null) {
12067            throw new NullPointerException("Configuration must not be null");
12068        }
12069
12070        synchronized(this) {
12071            final long origId = Binder.clearCallingIdentity();
12072            updateConfigurationLocked(values, null, true, false);
12073            Binder.restoreCallingIdentity(origId);
12074        }
12075    }
12076
12077    public void updateConfiguration(Configuration values) {
12078        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12079                "updateConfiguration()");
12080
12081        synchronized(this) {
12082            if (values == null && mWindowManager != null) {
12083                // sentinel: fetch the current configuration from the window manager
12084                values = mWindowManager.computeNewConfiguration();
12085            }
12086
12087            if (mWindowManager != null) {
12088                mProcessList.applyDisplaySize(mWindowManager);
12089            }
12090
12091            final long origId = Binder.clearCallingIdentity();
12092            if (values != null) {
12093                Settings.System.clearConfiguration(values);
12094            }
12095            updateConfigurationLocked(values, null, false, false);
12096            Binder.restoreCallingIdentity(origId);
12097        }
12098    }
12099
12100    /**
12101     * Do either or both things: (1) change the current configuration, and (2)
12102     * make sure the given activity is running with the (now) current
12103     * configuration.  Returns true if the activity has been left running, or
12104     * false if <var>starting</var> is being destroyed to match the new
12105     * configuration.
12106     * @param persistent TODO
12107     */
12108    boolean updateConfigurationLocked(Configuration values,
12109            ActivityRecord starting, boolean persistent, boolean initLocale) {
12110        // do nothing if we are headless
12111        if (mHeadless) return true;
12112
12113        int changes = 0;
12114
12115        boolean kept = true;
12116
12117        if (values != null) {
12118            Configuration newConfig = new Configuration(mConfiguration);
12119            changes = newConfig.updateFrom(values);
12120            if (changes != 0) {
12121                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12122                    Slog.i(TAG, "Updating configuration to: " + values);
12123                }
12124
12125                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12126
12127                if (values.locale != null && !initLocale) {
12128                    saveLocaleLocked(values.locale,
12129                                     !values.locale.equals(mConfiguration.locale),
12130                                     values.userSetLocale);
12131                }
12132
12133                mConfigurationSeq++;
12134                if (mConfigurationSeq <= 0) {
12135                    mConfigurationSeq = 1;
12136                }
12137                newConfig.seq = mConfigurationSeq;
12138                mConfiguration = newConfig;
12139                Slog.i(TAG, "Config changed: " + newConfig);
12140
12141                final Configuration configCopy = new Configuration(mConfiguration);
12142
12143                // TODO: If our config changes, should we auto dismiss any currently
12144                // showing dialogs?
12145                mShowDialogs = shouldShowDialogs(newConfig);
12146
12147                AttributeCache ac = AttributeCache.instance();
12148                if (ac != null) {
12149                    ac.updateConfiguration(configCopy);
12150                }
12151
12152                // Make sure all resources in our process are updated
12153                // right now, so that anyone who is going to retrieve
12154                // resource values after we return will be sure to get
12155                // the new ones.  This is especially important during
12156                // boot, where the first config change needs to guarantee
12157                // all resources have that config before following boot
12158                // code is executed.
12159                mSystemThread.applyConfigurationToResources(configCopy);
12160
12161                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12162                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12163                    msg.obj = new Configuration(configCopy);
12164                    mHandler.sendMessage(msg);
12165                }
12166
12167                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12168                    ProcessRecord app = mLruProcesses.get(i);
12169                    try {
12170                        if (app.thread != null) {
12171                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12172                                    + app.processName + " new config " + mConfiguration);
12173                            app.thread.scheduleConfigurationChanged(configCopy);
12174                        }
12175                    } catch (Exception e) {
12176                    }
12177                }
12178                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12179                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12180                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
12181                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12182                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12183                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12184                    broadcastIntentLocked(null, null,
12185                            new Intent(Intent.ACTION_LOCALE_CHANGED),
12186                            null, null, 0, null, null,
12187                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12188                }
12189            }
12190        }
12191
12192        if (changes != 0 && starting == null) {
12193            // If the configuration changed, and the caller is not already
12194            // in the process of starting an activity, then find the top
12195            // activity to check if its configuration needs to change.
12196            starting = mMainStack.topRunningActivityLocked(null);
12197        }
12198
12199        if (starting != null) {
12200            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12201            // And we need to make sure at this point that all other activities
12202            // are made visible with the correct configuration.
12203            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12204        }
12205
12206        if (values != null && mWindowManager != null) {
12207            mWindowManager.setNewConfiguration(mConfiguration);
12208        }
12209
12210        return kept;
12211    }
12212
12213    /**
12214     * Decide based on the configuration whether we should shouw the ANR,
12215     * crash, etc dialogs.  The idea is that if there is no affordnace to
12216     * press the on-screen buttons, we shouldn't show the dialog.
12217     *
12218     * A thought: SystemUI might also want to get told about this, the Power
12219     * dialog / global actions also might want different behaviors.
12220     */
12221    private static final boolean shouldShowDialogs(Configuration config) {
12222        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12223                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12224    }
12225
12226    /**
12227     * Save the locale.  You must be inside a synchronized (this) block.
12228     */
12229    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12230        if(isDiff) {
12231            SystemProperties.set("user.language", l.getLanguage());
12232            SystemProperties.set("user.region", l.getCountry());
12233        }
12234
12235        if(isPersist) {
12236            SystemProperties.set("persist.sys.language", l.getLanguage());
12237            SystemProperties.set("persist.sys.country", l.getCountry());
12238            SystemProperties.set("persist.sys.localevar", l.getVariant());
12239        }
12240    }
12241
12242    @Override
12243    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12244        ActivityRecord srec = ActivityRecord.forToken(token);
12245        return srec != null && srec.task.affinity != null &&
12246                srec.task.affinity.equals(destAffinity);
12247    }
12248
12249    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12250            Intent resultData) {
12251        ComponentName dest = destIntent.getComponent();
12252
12253        synchronized (this) {
12254            ActivityRecord srec = ActivityRecord.forToken(token);
12255            if (srec == null) {
12256                return false;
12257            }
12258            ArrayList<ActivityRecord> history = srec.stack.mHistory;
12259            final int start = history.indexOf(srec);
12260            if (start < 0) {
12261                // Current activity is not in history stack; do nothing.
12262                return false;
12263            }
12264            int finishTo = start - 1;
12265            ActivityRecord parent = null;
12266            boolean foundParentInTask = false;
12267            if (dest != null) {
12268                TaskRecord tr = srec.task;
12269                for (int i = start - 1; i >= 0; i--) {
12270                    ActivityRecord r = history.get(i);
12271                    if (tr != r.task) {
12272                        // Couldn't find parent in the same task; stop at the one above this.
12273                        // (Root of current task; in-app "home" behavior)
12274                        // Always at least finish the current activity.
12275                        finishTo = Math.min(start - 1, i + 1);
12276                        parent = history.get(finishTo);
12277                        break;
12278                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
12279                            r.info.name.equals(dest.getClassName())) {
12280                        finishTo = i;
12281                        parent = r;
12282                        foundParentInTask = true;
12283                        break;
12284                    }
12285                }
12286            }
12287
12288            if (mController != null) {
12289                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12290                if (next != null) {
12291                    // ask watcher if this is allowed
12292                    boolean resumeOK = true;
12293                    try {
12294                        resumeOK = mController.activityResuming(next.packageName);
12295                    } catch (RemoteException e) {
12296                        mController = null;
12297                    }
12298
12299                    if (!resumeOK) {
12300                        return false;
12301                    }
12302                }
12303            }
12304            final long origId = Binder.clearCallingIdentity();
12305            for (int i = start; i > finishTo; i--) {
12306                ActivityRecord r = history.get(i);
12307                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12308                        "navigate-up");
12309                // Only return the supplied result for the first activity finished
12310                resultCode = Activity.RESULT_CANCELED;
12311                resultData = null;
12312            }
12313
12314            if (parent != null && foundParentInTask) {
12315                final int parentLaunchMode = parent.info.launchMode;
12316                final int destIntentFlags = destIntent.getFlags();
12317                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12318                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12319                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12320                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12321                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12322                } else {
12323                    try {
12324                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12325                                destIntent.getComponent(), 0, UserHandle.getCallingUserId());
12326                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12327                                null, aInfo, parent.appToken, null,
12328                                0, -1, parent.launchedFromUid, 0, null, true, null);
12329                        foundParentInTask = res == ActivityManager.START_SUCCESS;
12330                    } catch (RemoteException e) {
12331                        foundParentInTask = false;
12332                    }
12333                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12334                            resultData, "navigate-up");
12335                }
12336            }
12337            Binder.restoreCallingIdentity(origId);
12338            return foundParentInTask;
12339        }
12340    }
12341
12342    public int getLaunchedFromUid(IBinder activityToken) {
12343        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12344        if (srec == null) {
12345            return -1;
12346        }
12347        return srec.launchedFromUid;
12348    }
12349
12350    // =========================================================
12351    // LIFETIME MANAGEMENT
12352    // =========================================================
12353
12354    // Returns which broadcast queue the app is the current [or imminent] receiver
12355    // on, or 'null' if the app is not an active broadcast recipient.
12356    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12357        BroadcastRecord r = app.curReceiver;
12358        if (r != null) {
12359            return r.queue;
12360        }
12361
12362        // It's not the current receiver, but it might be starting up to become one
12363        synchronized (this) {
12364            for (BroadcastQueue queue : mBroadcastQueues) {
12365                r = queue.mPendingBroadcast;
12366                if (r != null && r.curApp == app) {
12367                    // found it; report which queue it's in
12368                    return queue;
12369                }
12370            }
12371        }
12372
12373        return null;
12374    }
12375
12376    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12377            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12378        if (mAdjSeq == app.adjSeq) {
12379            // This adjustment has already been computed.  If we are calling
12380            // from the top, we may have already computed our adjustment with
12381            // an earlier hidden adjustment that isn't really for us... if
12382            // so, use the new hidden adjustment.
12383            if (!recursed && app.hidden) {
12384                app.curAdj = app.curRawAdj = app.nonStoppingAdj =
12385                        app.hasActivities ? hiddenAdj : emptyAdj;
12386            }
12387            return app.curRawAdj;
12388        }
12389
12390        if (app.thread == null) {
12391            app.adjSeq = mAdjSeq;
12392            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12393            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12394        }
12395
12396        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12397        app.adjSource = null;
12398        app.adjTarget = null;
12399        app.empty = false;
12400        app.hidden = false;
12401
12402        final int activitiesSize = app.activities.size();
12403
12404        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12405            // The max adjustment doesn't allow this app to be anything
12406            // below foreground, so it is not worth doing work for it.
12407            app.adjType = "fixed";
12408            app.adjSeq = mAdjSeq;
12409            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12410            app.hasActivities = false;
12411            app.foregroundActivities = false;
12412            app.keeping = true;
12413            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12414            // System process can do UI, and when they do we want to have
12415            // them trim their memory after the user leaves the UI.  To
12416            // facilitate this, here we need to determine whether or not it
12417            // is currently showing UI.
12418            app.systemNoUi = true;
12419            if (app == TOP_APP) {
12420                app.systemNoUi = false;
12421                app.hasActivities = true;
12422            } else if (activitiesSize > 0) {
12423                for (int j = 0; j < activitiesSize; j++) {
12424                    final ActivityRecord r = app.activities.get(j);
12425                    if (r.visible) {
12426                        app.systemNoUi = false;
12427                    }
12428                    if (r.app == app) {
12429                        app.hasActivities = true;
12430                    }
12431                }
12432            }
12433            return (app.curAdj=app.maxAdj);
12434        }
12435
12436        app.keeping = false;
12437        app.systemNoUi = false;
12438        app.hasActivities = false;
12439
12440        // Determine the importance of the process, starting with most
12441        // important to least, and assign an appropriate OOM adjustment.
12442        int adj;
12443        int schedGroup;
12444        boolean foregroundActivities = false;
12445        boolean interesting = false;
12446        BroadcastQueue queue;
12447        if (app == TOP_APP) {
12448            // The last app on the list is the foreground app.
12449            adj = ProcessList.FOREGROUND_APP_ADJ;
12450            schedGroup = Process.THREAD_GROUP_DEFAULT;
12451            app.adjType = "top-activity";
12452            foregroundActivities = true;
12453            interesting = true;
12454            app.hasActivities = true;
12455        } else if (app.instrumentationClass != null) {
12456            // Don't want to kill running instrumentation.
12457            adj = ProcessList.FOREGROUND_APP_ADJ;
12458            schedGroup = Process.THREAD_GROUP_DEFAULT;
12459            app.adjType = "instrumentation";
12460            interesting = true;
12461        } else if ((queue = isReceivingBroadcast(app)) != null) {
12462            // An app that is currently receiving a broadcast also
12463            // counts as being in the foreground for OOM killer purposes.
12464            // It's placed in a sched group based on the nature of the
12465            // broadcast as reflected by which queue it's active in.
12466            adj = ProcessList.FOREGROUND_APP_ADJ;
12467            schedGroup = (queue == mFgBroadcastQueue)
12468                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12469            app.adjType = "broadcast";
12470        } else if (app.executingServices.size() > 0) {
12471            // An app that is currently executing a service callback also
12472            // counts as being in the foreground.
12473            adj = ProcessList.FOREGROUND_APP_ADJ;
12474            schedGroup = Process.THREAD_GROUP_DEFAULT;
12475            app.adjType = "exec-service";
12476        } else {
12477            // Assume process is hidden (has activities); we will correct
12478            // later if this is not the case.
12479            adj = hiddenAdj;
12480            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12481            app.hidden = true;
12482            app.adjType = "bg-activities";
12483        }
12484
12485        boolean hasStoppingActivities = false;
12486
12487        // Examine all activities if not already foreground.
12488        if (!foregroundActivities && activitiesSize > 0) {
12489            for (int j = 0; j < activitiesSize; j++) {
12490                final ActivityRecord r = app.activities.get(j);
12491                if (r.visible) {
12492                    // App has a visible activity; only upgrade adjustment.
12493                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12494                        adj = ProcessList.VISIBLE_APP_ADJ;
12495                        app.adjType = "visible";
12496                    }
12497                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12498                    app.hidden = false;
12499                    app.hasActivities = true;
12500                    foregroundActivities = true;
12501                    break;
12502                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12503                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12504                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12505                        app.adjType = "pausing";
12506                    }
12507                    app.hidden = false;
12508                    foregroundActivities = true;
12509                } else if (r.state == ActivityState.STOPPING) {
12510                    // We will apply the actual adjustment later, because
12511                    // we want to allow this process to immediately go through
12512                    // any memory trimming that is in effect.
12513                    app.hidden = false;
12514                    foregroundActivities = true;
12515                    hasStoppingActivities = true;
12516                }
12517                if (r.app == app) {
12518                    app.hasActivities = true;
12519                }
12520            }
12521        }
12522
12523        if (adj == hiddenAdj && !app.hasActivities) {
12524            // Whoops, this process is completely empty as far as we know
12525            // at this point.
12526            adj = emptyAdj;
12527            app.empty = true;
12528            app.adjType = "bg-empty";
12529        }
12530
12531        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12532            if (app.foregroundServices) {
12533                // The user is aware of this app, so make it visible.
12534                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12535                app.hidden = false;
12536                app.adjType = "foreground-service";
12537                schedGroup = Process.THREAD_GROUP_DEFAULT;
12538            } else if (app.forcingToForeground != null) {
12539                // The user is aware of this app, so make it visible.
12540                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12541                app.hidden = false;
12542                app.adjType = "force-foreground";
12543                app.adjSource = app.forcingToForeground;
12544                schedGroup = Process.THREAD_GROUP_DEFAULT;
12545            }
12546        }
12547
12548        if (app.foregroundServices) {
12549            interesting = true;
12550        }
12551
12552        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12553            // We don't want to kill the current heavy-weight process.
12554            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12555            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12556            app.hidden = false;
12557            app.adjType = "heavy";
12558        }
12559
12560        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12561            // This process is hosting what we currently consider to be the
12562            // home app, so we don't want to let it go into the background.
12563            adj = ProcessList.HOME_APP_ADJ;
12564            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12565            app.hidden = false;
12566            app.adjType = "home";
12567        }
12568
12569        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12570                && app.activities.size() > 0) {
12571            // This was the previous process that showed UI to the user.
12572            // We want to try to keep it around more aggressively, to give
12573            // a good experience around switching between two apps.
12574            adj = ProcessList.PREVIOUS_APP_ADJ;
12575            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12576            app.hidden = false;
12577            app.adjType = "previous";
12578        }
12579
12580        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12581                + " reason=" + app.adjType);
12582
12583        // By default, we use the computed adjustment.  It may be changed if
12584        // there are applications dependent on our services or providers, but
12585        // this gives us a baseline and makes sure we don't get into an
12586        // infinite recursion.
12587        app.adjSeq = mAdjSeq;
12588        app.curRawAdj = app.nonStoppingAdj = adj;
12589
12590        if (mBackupTarget != null && app == mBackupTarget.app) {
12591            // If possible we want to avoid killing apps while they're being backed up
12592            if (adj > ProcessList.BACKUP_APP_ADJ) {
12593                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12594                adj = ProcessList.BACKUP_APP_ADJ;
12595                app.adjType = "backup";
12596                app.hidden = false;
12597            }
12598        }
12599
12600        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12601                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12602            final long now = SystemClock.uptimeMillis();
12603            // This process is more important if the top activity is
12604            // bound to the service.
12605            Iterator<ServiceRecord> jt = app.services.iterator();
12606            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12607                ServiceRecord s = jt.next();
12608                if (s.startRequested) {
12609                    if (app.hasShownUi && app != mHomeProcess) {
12610                        // If this process has shown some UI, let it immediately
12611                        // go to the LRU list because it may be pretty heavy with
12612                        // UI stuff.  We'll tag it with a label just to help
12613                        // debug and understand what is going on.
12614                        if (adj > ProcessList.SERVICE_ADJ) {
12615                            app.adjType = "started-bg-ui-services";
12616                        }
12617                    } else {
12618                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12619                            // This service has seen some activity within
12620                            // recent memory, so we will keep its process ahead
12621                            // of the background processes.
12622                            if (adj > ProcessList.SERVICE_ADJ) {
12623                                adj = ProcessList.SERVICE_ADJ;
12624                                app.adjType = "started-services";
12625                                app.hidden = false;
12626                            }
12627                        }
12628                        // If we have let the service slide into the background
12629                        // state, still have some text describing what it is doing
12630                        // even though the service no longer has an impact.
12631                        if (adj > ProcessList.SERVICE_ADJ) {
12632                            app.adjType = "started-bg-services";
12633                        }
12634                    }
12635                    // Don't kill this process because it is doing work; it
12636                    // has said it is doing work.
12637                    app.keeping = true;
12638                }
12639                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12640                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12641                    Iterator<ArrayList<ConnectionRecord>> kt
12642                            = s.connections.values().iterator();
12643                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12644                        ArrayList<ConnectionRecord> clist = kt.next();
12645                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12646                            // XXX should compute this based on the max of
12647                            // all connected clients.
12648                            ConnectionRecord cr = clist.get(i);
12649                            if (cr.binding.client == app) {
12650                                // Binding to ourself is not interesting.
12651                                continue;
12652                            }
12653                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12654                                ProcessRecord client = cr.binding.client;
12655                                int clientAdj = adj;
12656                                int myHiddenAdj = hiddenAdj;
12657                                if (myHiddenAdj > client.hiddenAdj) {
12658                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12659                                        myHiddenAdj = client.hiddenAdj;
12660                                    } else {
12661                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12662                                    }
12663                                }
12664                                int myEmptyAdj = emptyAdj;
12665                                if (myEmptyAdj > client.emptyAdj) {
12666                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12667                                        myEmptyAdj = client.emptyAdj;
12668                                    } else {
12669                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12670                                    }
12671                                }
12672                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12673                                        myEmptyAdj, TOP_APP, true, doingAll);
12674                                String adjType = null;
12675                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12676                                    // Not doing bind OOM management, so treat
12677                                    // this guy more like a started service.
12678                                    if (app.hasShownUi && app != mHomeProcess) {
12679                                        // If this process has shown some UI, let it immediately
12680                                        // go to the LRU list because it may be pretty heavy with
12681                                        // UI stuff.  We'll tag it with a label just to help
12682                                        // debug and understand what is going on.
12683                                        if (adj > clientAdj) {
12684                                            adjType = "bound-bg-ui-services";
12685                                        }
12686                                        app.hidden = false;
12687                                        clientAdj = adj;
12688                                    } else {
12689                                        if (now >= (s.lastActivity
12690                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12691                                            // This service has not seen activity within
12692                                            // recent memory, so allow it to drop to the
12693                                            // LRU list if there is no other reason to keep
12694                                            // it around.  We'll also tag it with a label just
12695                                            // to help debug and undertand what is going on.
12696                                            if (adj > clientAdj) {
12697                                                adjType = "bound-bg-services";
12698                                            }
12699                                            clientAdj = adj;
12700                                        }
12701                                    }
12702                                }
12703                                if (adj > clientAdj) {
12704                                    // If this process has recently shown UI, and
12705                                    // the process that is binding to it is less
12706                                    // important than being visible, then we don't
12707                                    // care about the binding as much as we care
12708                                    // about letting this process get into the LRU
12709                                    // list to be killed and restarted if needed for
12710                                    // memory.
12711                                    if (app.hasShownUi && app != mHomeProcess
12712                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12713                                        adjType = "bound-bg-ui-services";
12714                                    } else {
12715                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12716                                                |Context.BIND_IMPORTANT)) != 0) {
12717                                            adj = clientAdj;
12718                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12719                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12720                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12721                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12722                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12723                                            adj = clientAdj;
12724                                        } else {
12725                                            app.pendingUiClean = true;
12726                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12727                                                adj = ProcessList.VISIBLE_APP_ADJ;
12728                                            }
12729                                        }
12730                                        if (!client.hidden) {
12731                                            app.hidden = false;
12732                                        }
12733                                        if (client.keeping) {
12734                                            app.keeping = true;
12735                                        }
12736                                        adjType = "service";
12737                                    }
12738                                }
12739                                if (adjType != null) {
12740                                    app.adjType = adjType;
12741                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12742                                            .REASON_SERVICE_IN_USE;
12743                                    app.adjSource = cr.binding.client;
12744                                    app.adjSourceOom = clientAdj;
12745                                    app.adjTarget = s.name;
12746                                }
12747                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12748                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12749                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12750                                    }
12751                                }
12752                            }
12753                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12754                                ActivityRecord a = cr.activity;
12755                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12756                                        (a.visible || a.state == ActivityState.RESUMED
12757                                         || a.state == ActivityState.PAUSING)) {
12758                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12759                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12760                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12761                                    }
12762                                    app.hidden = false;
12763                                    app.adjType = "service";
12764                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12765                                            .REASON_SERVICE_IN_USE;
12766                                    app.adjSource = a;
12767                                    app.adjSourceOom = adj;
12768                                    app.adjTarget = s.name;
12769                                }
12770                            }
12771                        }
12772                    }
12773                }
12774            }
12775
12776            // Finally, if this process has active services running in it, we
12777            // would like to avoid killing it unless it would prevent the current
12778            // application from running.  By default we put the process in
12779            // with the rest of the background processes; as we scan through
12780            // its services we may bump it up from there.
12781            if (adj > hiddenAdj) {
12782                adj = hiddenAdj;
12783                app.hidden = false;
12784                app.adjType = "bg-services";
12785            }
12786        }
12787
12788        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12789                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12790            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12791            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12792                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12793                ContentProviderRecord cpr = jt.next();
12794                for (int i = cpr.connections.size()-1;
12795                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12796                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12797                        i--) {
12798                    ContentProviderConnection conn = cpr.connections.get(i);
12799                    ProcessRecord client = conn.client;
12800                    if (client == app) {
12801                        // Being our own client is not interesting.
12802                        continue;
12803                    }
12804                    int myHiddenAdj = hiddenAdj;
12805                    if (myHiddenAdj > client.hiddenAdj) {
12806                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12807                            myHiddenAdj = client.hiddenAdj;
12808                        } else {
12809                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12810                        }
12811                    }
12812                    int myEmptyAdj = emptyAdj;
12813                    if (myEmptyAdj > client.emptyAdj) {
12814                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12815                            myEmptyAdj = client.emptyAdj;
12816                        } else {
12817                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12818                        }
12819                    }
12820                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12821                            myEmptyAdj, TOP_APP, true, doingAll);
12822                    if (adj > clientAdj) {
12823                        if (app.hasShownUi && app != mHomeProcess
12824                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12825                            app.adjType = "bg-ui-provider";
12826                        } else {
12827                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12828                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12829                            app.adjType = "provider";
12830                        }
12831                        if (!client.hidden) {
12832                            app.hidden = false;
12833                        }
12834                        if (client.keeping) {
12835                            app.keeping = true;
12836                        }
12837                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12838                                .REASON_PROVIDER_IN_USE;
12839                        app.adjSource = client;
12840                        app.adjSourceOom = clientAdj;
12841                        app.adjTarget = cpr.name;
12842                    }
12843                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12844                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12845                    }
12846                }
12847                // If the provider has external (non-framework) process
12848                // dependencies, ensure that its adjustment is at least
12849                // FOREGROUND_APP_ADJ.
12850                if (cpr.hasExternalProcessHandles()) {
12851                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12852                        adj = ProcessList.FOREGROUND_APP_ADJ;
12853                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12854                        app.hidden = false;
12855                        app.keeping = true;
12856                        app.adjType = "provider";
12857                        app.adjTarget = cpr.name;
12858                    }
12859                }
12860            }
12861        }
12862
12863        if (adj == ProcessList.SERVICE_ADJ) {
12864            if (doingAll) {
12865                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12866                mNewNumServiceProcs++;
12867            }
12868            if (app.serviceb) {
12869                adj = ProcessList.SERVICE_B_ADJ;
12870            }
12871        } else {
12872            app.serviceb = false;
12873        }
12874
12875        app.nonStoppingAdj = adj;
12876
12877        if (hasStoppingActivities) {
12878            // Only upgrade adjustment.
12879            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12880                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12881                app.adjType = "stopping";
12882            }
12883        }
12884
12885        app.curRawAdj = adj;
12886
12887        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12888        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12889        if (adj > app.maxAdj) {
12890            adj = app.maxAdj;
12891            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12892                schedGroup = Process.THREAD_GROUP_DEFAULT;
12893            }
12894        }
12895        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12896            app.keeping = true;
12897        }
12898
12899        if (app.hasAboveClient) {
12900            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12901            // then we need to drop its adjustment to be lower than the service's
12902            // in order to honor the request.  We want to drop it by one adjustment
12903            // level...  but there is special meaning applied to various levels so
12904            // we will skip some of them.
12905            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12906                // System process will not get dropped, ever
12907            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12908                adj = ProcessList.VISIBLE_APP_ADJ;
12909            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12910                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12911            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12912                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
12913            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
12914                adj++;
12915            }
12916        }
12917
12918        int importance = app.memImportance;
12919        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
12920            app.curAdj = adj;
12921            app.curSchedGroup = schedGroup;
12922            if (!interesting) {
12923                // For this reporting, if there is not something explicitly
12924                // interesting in this process then we will push it to the
12925                // background importance.
12926                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12927            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12928                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12929            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
12930                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12931            } else if (adj >= ProcessList.HOME_APP_ADJ) {
12932                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12933            } else if (adj >= ProcessList.SERVICE_ADJ) {
12934                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12935            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12936                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
12937            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
12938                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
12939            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
12940                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
12941            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
12942                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
12943            } else {
12944                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
12945            }
12946        }
12947
12948        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
12949        if (foregroundActivities != app.foregroundActivities) {
12950            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
12951        }
12952        if (changes != 0) {
12953            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
12954            app.memImportance = importance;
12955            app.foregroundActivities = foregroundActivities;
12956            int i = mPendingProcessChanges.size()-1;
12957            ProcessChangeItem item = null;
12958            while (i >= 0) {
12959                item = mPendingProcessChanges.get(i);
12960                if (item.pid == app.pid) {
12961                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
12962                    break;
12963                }
12964                i--;
12965            }
12966            if (i < 0) {
12967                // No existing item in pending changes; need a new one.
12968                final int NA = mAvailProcessChanges.size();
12969                if (NA > 0) {
12970                    item = mAvailProcessChanges.remove(NA-1);
12971                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
12972                } else {
12973                    item = new ProcessChangeItem();
12974                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
12975                }
12976                item.changes = 0;
12977                item.pid = app.pid;
12978                item.uid = app.info.uid;
12979                if (mPendingProcessChanges.size() == 0) {
12980                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
12981                            "*** Enqueueing dispatch processes changed!");
12982                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
12983                }
12984                mPendingProcessChanges.add(item);
12985            }
12986            item.changes |= changes;
12987            item.importance = importance;
12988            item.foregroundActivities = foregroundActivities;
12989            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
12990                    + Integer.toHexString(System.identityHashCode(item))
12991                    + " " + app.toShortString() + ": changes=" + item.changes
12992                    + " importance=" + item.importance
12993                    + " foreground=" + item.foregroundActivities
12994                    + " type=" + app.adjType + " source=" + app.adjSource
12995                    + " target=" + app.adjTarget);
12996        }
12997
12998        return app.curRawAdj;
12999    }
13000
13001    /**
13002     * Ask a given process to GC right now.
13003     */
13004    final void performAppGcLocked(ProcessRecord app) {
13005        try {
13006            app.lastRequestedGc = SystemClock.uptimeMillis();
13007            if (app.thread != null) {
13008                if (app.reportLowMemory) {
13009                    app.reportLowMemory = false;
13010                    app.thread.scheduleLowMemory();
13011                } else {
13012                    app.thread.processInBackground();
13013                }
13014            }
13015        } catch (Exception e) {
13016            // whatever.
13017        }
13018    }
13019
13020    /**
13021     * Returns true if things are idle enough to perform GCs.
13022     */
13023    private final boolean canGcNowLocked() {
13024        boolean processingBroadcasts = false;
13025        for (BroadcastQueue q : mBroadcastQueues) {
13026            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13027                processingBroadcasts = true;
13028            }
13029        }
13030        return !processingBroadcasts
13031                && (mSleeping || (mMainStack.mResumedActivity != null &&
13032                        mMainStack.mResumedActivity.idle));
13033    }
13034
13035    /**
13036     * Perform GCs on all processes that are waiting for it, but only
13037     * if things are idle.
13038     */
13039    final void performAppGcsLocked() {
13040        final int N = mProcessesToGc.size();
13041        if (N <= 0) {
13042            return;
13043        }
13044        if (canGcNowLocked()) {
13045            while (mProcessesToGc.size() > 0) {
13046                ProcessRecord proc = mProcessesToGc.remove(0);
13047                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
13048                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13049                            <= SystemClock.uptimeMillis()) {
13050                        // To avoid spamming the system, we will GC processes one
13051                        // at a time, waiting a few seconds between each.
13052                        performAppGcLocked(proc);
13053                        scheduleAppGcsLocked();
13054                        return;
13055                    } else {
13056                        // It hasn't been long enough since we last GCed this
13057                        // process...  put it in the list to wait for its time.
13058                        addProcessToGcListLocked(proc);
13059                        break;
13060                    }
13061                }
13062            }
13063
13064            scheduleAppGcsLocked();
13065        }
13066    }
13067
13068    /**
13069     * If all looks good, perform GCs on all processes waiting for them.
13070     */
13071    final void performAppGcsIfAppropriateLocked() {
13072        if (canGcNowLocked()) {
13073            performAppGcsLocked();
13074            return;
13075        }
13076        // Still not idle, wait some more.
13077        scheduleAppGcsLocked();
13078    }
13079
13080    /**
13081     * Schedule the execution of all pending app GCs.
13082     */
13083    final void scheduleAppGcsLocked() {
13084        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13085
13086        if (mProcessesToGc.size() > 0) {
13087            // Schedule a GC for the time to the next process.
13088            ProcessRecord proc = mProcessesToGc.get(0);
13089            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13090
13091            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13092            long now = SystemClock.uptimeMillis();
13093            if (when < (now+GC_TIMEOUT)) {
13094                when = now + GC_TIMEOUT;
13095            }
13096            mHandler.sendMessageAtTime(msg, when);
13097        }
13098    }
13099
13100    /**
13101     * Add a process to the array of processes waiting to be GCed.  Keeps the
13102     * list in sorted order by the last GC time.  The process can't already be
13103     * on the list.
13104     */
13105    final void addProcessToGcListLocked(ProcessRecord proc) {
13106        boolean added = false;
13107        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13108            if (mProcessesToGc.get(i).lastRequestedGc <
13109                    proc.lastRequestedGc) {
13110                added = true;
13111                mProcessesToGc.add(i+1, proc);
13112                break;
13113            }
13114        }
13115        if (!added) {
13116            mProcessesToGc.add(0, proc);
13117        }
13118    }
13119
13120    /**
13121     * Set up to ask a process to GC itself.  This will either do it
13122     * immediately, or put it on the list of processes to gc the next
13123     * time things are idle.
13124     */
13125    final void scheduleAppGcLocked(ProcessRecord app) {
13126        long now = SystemClock.uptimeMillis();
13127        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13128            return;
13129        }
13130        if (!mProcessesToGc.contains(app)) {
13131            addProcessToGcListLocked(app);
13132            scheduleAppGcsLocked();
13133        }
13134    }
13135
13136    final void checkExcessivePowerUsageLocked(boolean doKills) {
13137        updateCpuStatsNow();
13138
13139        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13140        boolean doWakeKills = doKills;
13141        boolean doCpuKills = doKills;
13142        if (mLastPowerCheckRealtime == 0) {
13143            doWakeKills = false;
13144        }
13145        if (mLastPowerCheckUptime == 0) {
13146            doCpuKills = false;
13147        }
13148        if (stats.isScreenOn()) {
13149            doWakeKills = false;
13150        }
13151        final long curRealtime = SystemClock.elapsedRealtime();
13152        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13153        final long curUptime = SystemClock.uptimeMillis();
13154        final long uptimeSince = curUptime - mLastPowerCheckUptime;
13155        mLastPowerCheckRealtime = curRealtime;
13156        mLastPowerCheckUptime = curUptime;
13157        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13158            doWakeKills = false;
13159        }
13160        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13161            doCpuKills = false;
13162        }
13163        int i = mLruProcesses.size();
13164        while (i > 0) {
13165            i--;
13166            ProcessRecord app = mLruProcesses.get(i);
13167            if (!app.keeping) {
13168                long wtime;
13169                synchronized (stats) {
13170                    wtime = stats.getProcessWakeTime(app.info.uid,
13171                            app.pid, curRealtime);
13172                }
13173                long wtimeUsed = wtime - app.lastWakeTime;
13174                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13175                if (DEBUG_POWER) {
13176                    StringBuilder sb = new StringBuilder(128);
13177                    sb.append("Wake for ");
13178                    app.toShortString(sb);
13179                    sb.append(": over ");
13180                    TimeUtils.formatDuration(realtimeSince, sb);
13181                    sb.append(" used ");
13182                    TimeUtils.formatDuration(wtimeUsed, sb);
13183                    sb.append(" (");
13184                    sb.append((wtimeUsed*100)/realtimeSince);
13185                    sb.append("%)");
13186                    Slog.i(TAG, sb.toString());
13187                    sb.setLength(0);
13188                    sb.append("CPU for ");
13189                    app.toShortString(sb);
13190                    sb.append(": over ");
13191                    TimeUtils.formatDuration(uptimeSince, sb);
13192                    sb.append(" used ");
13193                    TimeUtils.formatDuration(cputimeUsed, sb);
13194                    sb.append(" (");
13195                    sb.append((cputimeUsed*100)/uptimeSince);
13196                    sb.append("%)");
13197                    Slog.i(TAG, sb.toString());
13198                }
13199                // If a process has held a wake lock for more
13200                // than 50% of the time during this period,
13201                // that sounds bad.  Kill!
13202                if (doWakeKills && realtimeSince > 0
13203                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
13204                    synchronized (stats) {
13205                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13206                                realtimeSince, wtimeUsed);
13207                    }
13208                    Slog.w(TAG, "Excessive wake lock in " + app.processName
13209                            + " (pid " + app.pid + "): held " + wtimeUsed
13210                            + " during " + realtimeSince);
13211                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13212                            app.processName, app.setAdj, "excessive wake lock");
13213                    Process.killProcessQuiet(app.pid);
13214                } else if (doCpuKills && uptimeSince > 0
13215                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
13216                    synchronized (stats) {
13217                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13218                                uptimeSince, cputimeUsed);
13219                    }
13220                    Slog.w(TAG, "Excessive CPU in " + app.processName
13221                            + " (pid " + app.pid + "): used " + cputimeUsed
13222                            + " during " + uptimeSince);
13223                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13224                            app.processName, app.setAdj, "excessive cpu");
13225                    Process.killProcessQuiet(app.pid);
13226                } else {
13227                    app.lastWakeTime = wtime;
13228                    app.lastCpuTime = app.curCpuTime;
13229                }
13230            }
13231        }
13232    }
13233
13234    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13235            int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13236        app.hiddenAdj = hiddenAdj;
13237        app.emptyAdj = emptyAdj;
13238
13239        if (app.thread == null) {
13240            return false;
13241        }
13242
13243        final boolean wasKeeping = app.keeping;
13244
13245        boolean success = true;
13246
13247        computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13248
13249        if (app.curRawAdj != app.setRawAdj) {
13250            if (wasKeeping && !app.keeping) {
13251                // This app is no longer something we want to keep.  Note
13252                // its current wake lock time to later know to kill it if
13253                // it is not behaving well.
13254                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13255                synchronized (stats) {
13256                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13257                            app.pid, SystemClock.elapsedRealtime());
13258                }
13259                app.lastCpuTime = app.curCpuTime;
13260            }
13261
13262            app.setRawAdj = app.curRawAdj;
13263        }
13264
13265        if (app.curAdj != app.setAdj) {
13266            if (Process.setOomAdj(app.pid, app.curAdj)) {
13267                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13268                    TAG, "Set " + app.pid + " " + app.processName +
13269                    " adj " + app.curAdj + ": " + app.adjType);
13270                app.setAdj = app.curAdj;
13271            } else {
13272                success = false;
13273                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13274            }
13275        }
13276        if (app.setSchedGroup != app.curSchedGroup) {
13277            app.setSchedGroup = app.curSchedGroup;
13278            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13279                    "Setting process group of " + app.processName
13280                    + " to " + app.curSchedGroup);
13281            if (app.waitingToKill != null &&
13282                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13283                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13284                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13285                        app.processName, app.setAdj, app.waitingToKill);
13286                app.killedBackground = true;
13287                Process.killProcessQuiet(app.pid);
13288                success = false;
13289            } else {
13290                if (true) {
13291                    long oldId = Binder.clearCallingIdentity();
13292                    try {
13293                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13294                    } catch (Exception e) {
13295                        Slog.w(TAG, "Failed setting process group of " + app.pid
13296                                + " to " + app.curSchedGroup);
13297                        e.printStackTrace();
13298                    } finally {
13299                        Binder.restoreCallingIdentity(oldId);
13300                    }
13301                } else {
13302                    if (app.thread != null) {
13303                        try {
13304                            app.thread.setSchedulingGroup(app.curSchedGroup);
13305                        } catch (RemoteException e) {
13306                        }
13307                    }
13308                }
13309            }
13310        }
13311        return success;
13312    }
13313
13314    private final ActivityRecord resumedAppLocked() {
13315        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13316        if (resumedActivity == null || resumedActivity.app == null) {
13317            resumedActivity = mMainStack.mPausingActivity;
13318            if (resumedActivity == null || resumedActivity.app == null) {
13319                resumedActivity = mMainStack.topRunningActivityLocked(null);
13320            }
13321        }
13322        return resumedActivity;
13323    }
13324
13325    final boolean updateOomAdjLocked(ProcessRecord app) {
13326        final ActivityRecord TOP_ACT = resumedAppLocked();
13327        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13328        int curAdj = app.curAdj;
13329        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13330            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13331
13332        mAdjSeq++;
13333
13334        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
13335                TOP_APP, false);
13336        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13337            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13338        if (nowHidden != wasHidden) {
13339            // Changed to/from hidden state, so apps after it in the LRU
13340            // list may also be changed.
13341            updateOomAdjLocked();
13342        }
13343        return success;
13344    }
13345
13346    final void updateOomAdjLocked() {
13347        final ActivityRecord TOP_ACT = resumedAppLocked();
13348        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13349
13350        if (false) {
13351            RuntimeException e = new RuntimeException();
13352            e.fillInStackTrace();
13353            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13354        }
13355
13356        mAdjSeq++;
13357        mNewNumServiceProcs = 0;
13358
13359        // Let's determine how many processes we have running vs.
13360        // how many slots we have for background processes; we may want
13361        // to put multiple processes in a slot of there are enough of
13362        // them.
13363        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13364                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13365        int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
13366        if (emptyFactor < 1) emptyFactor = 1;
13367        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13368        if (hiddenFactor < 1) hiddenFactor = 1;
13369        int stepHidden = 0;
13370        int stepEmpty = 0;
13371        final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13372        final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13373        int numHidden = 0;
13374        int numEmpty = 0;
13375        int numTrimming = 0;
13376
13377        mNumNonHiddenProcs = 0;
13378        mNumHiddenProcs = 0;
13379
13380        // First update the OOM adjustment for each of the
13381        // application processes based on their current state.
13382        int i = mLruProcesses.size();
13383        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13384        int nextHiddenAdj = curHiddenAdj+1;
13385        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13386        int nextEmptyAdj = curEmptyAdj+2;
13387        while (i > 0) {
13388            i--;
13389            ProcessRecord app = mLruProcesses.get(i);
13390            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13391            updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
13392            if (!app.killedBackground) {
13393                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13394                    // This process was assigned as a hidden process...  step the
13395                    // hidden level.
13396                    mNumHiddenProcs++;
13397                    if (curHiddenAdj != nextHiddenAdj) {
13398                        stepHidden++;
13399                        if (stepHidden >= hiddenFactor) {
13400                            stepHidden = 0;
13401                            curHiddenAdj = nextHiddenAdj;
13402                            nextHiddenAdj += 2;
13403                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13404                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13405                            }
13406                        }
13407                    }
13408                    numHidden++;
13409                    if (numHidden > hiddenProcessLimit) {
13410                        Slog.i(TAG, "No longer want " + app.processName
13411                                + " (pid " + app.pid + "): hidden #" + numHidden);
13412                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13413                                app.processName, app.setAdj, "too many background");
13414                        app.killedBackground = true;
13415                        Process.killProcessQuiet(app.pid);
13416                    }
13417                } else {
13418                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13419                        // This process was assigned as an empty process...  step the
13420                        // empty level.
13421                        if (curEmptyAdj != nextEmptyAdj) {
13422                            stepEmpty++;
13423                            if (stepEmpty >= emptyFactor) {
13424                                stepEmpty = 0;
13425                                curEmptyAdj = nextEmptyAdj;
13426                                nextEmptyAdj += 2;
13427                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13428                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13429                                }
13430                            }
13431                        }
13432                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13433                        mNumNonHiddenProcs++;
13434                    }
13435                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13436                        numEmpty++;
13437                        if (numEmpty > emptyProcessLimit) {
13438                            Slog.i(TAG, "No longer want " + app.processName
13439                                    + " (pid " + app.pid + "): empty #" + numEmpty);
13440                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13441                                    app.processName, app.setAdj, "too many background");
13442                            app.killedBackground = true;
13443                            Process.killProcessQuiet(app.pid);
13444                        }
13445                    }
13446                }
13447                if (app.isolated && app.services.size() <= 0) {
13448                    // If this is an isolated process, and there are no
13449                    // services running in it, then the process is no longer
13450                    // needed.  We agressively kill these because we can by
13451                    // definition not re-use the same process again, and it is
13452                    // good to avoid having whatever code was running in them
13453                    // left sitting around after no longer needed.
13454                    Slog.i(TAG, "Isolated process " + app.processName
13455                            + " (pid " + app.pid + ") no longer needed");
13456                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13457                            app.processName, app.setAdj, "isolated not needed");
13458                    app.killedBackground = true;
13459                    Process.killProcessQuiet(app.pid);
13460                }
13461                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13462                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13463                        && !app.killedBackground) {
13464                    numTrimming++;
13465                }
13466            }
13467        }
13468
13469        mNumServiceProcs = mNewNumServiceProcs;
13470
13471        // Now determine the memory trimming level of background processes.
13472        // Unfortunately we need to start at the back of the list to do this
13473        // properly.  We only do this if the number of background apps we
13474        // are managing to keep around is less than half the maximum we desire;
13475        // if we are keeping a good number around, we'll let them use whatever
13476        // memory they want.
13477        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13478                && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13479            final int numHiddenAndEmpty = numHidden + numEmpty;
13480            final int N = mLruProcesses.size();
13481            int factor = numTrimming/3;
13482            int minFactor = 2;
13483            if (mHomeProcess != null) minFactor++;
13484            if (mPreviousProcess != null) minFactor++;
13485            if (factor < minFactor) factor = minFactor;
13486            int step = 0;
13487            int fgTrimLevel;
13488            if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13489                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13490            } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13491                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13492            } else {
13493                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13494            }
13495            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13496            for (i=0; i<N; i++) {
13497                ProcessRecord app = mLruProcesses.get(i);
13498                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13499                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13500                        && !app.killedBackground) {
13501                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13502                        try {
13503                            app.thread.scheduleTrimMemory(curLevel);
13504                        } catch (RemoteException e) {
13505                        }
13506                        if (false) {
13507                            // For now we won't do this; our memory trimming seems
13508                            // to be good enough at this point that destroying
13509                            // activities causes more harm than good.
13510                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13511                                    && app != mHomeProcess && app != mPreviousProcess) {
13512                                // Need to do this on its own message because the stack may not
13513                                // be in a consistent state at this point.
13514                                // For these apps we will also finish their activities
13515                                // to help them free memory.
13516                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13517                            }
13518                        }
13519                    }
13520                    app.trimMemoryLevel = curLevel;
13521                    step++;
13522                    if (step >= factor) {
13523                        step = 0;
13524                        switch (curLevel) {
13525                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13526                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13527                                break;
13528                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13529                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13530                                break;
13531                        }
13532                    }
13533                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13534                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13535                            && app.thread != null) {
13536                        try {
13537                            app.thread.scheduleTrimMemory(
13538                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13539                        } catch (RemoteException e) {
13540                        }
13541                    }
13542                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13543                } else {
13544                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13545                            && app.pendingUiClean) {
13546                        // If this application is now in the background and it
13547                        // had done UI, then give it the special trim level to
13548                        // have it free UI resources.
13549                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13550                        if (app.trimMemoryLevel < level && app.thread != null) {
13551                            try {
13552                                app.thread.scheduleTrimMemory(level);
13553                            } catch (RemoteException e) {
13554                            }
13555                        }
13556                        app.pendingUiClean = false;
13557                    }
13558                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13559                        try {
13560                            app.thread.scheduleTrimMemory(fgTrimLevel);
13561                        } catch (RemoteException e) {
13562                        }
13563                    }
13564                    app.trimMemoryLevel = fgTrimLevel;
13565                }
13566            }
13567        } else {
13568            final int N = mLruProcesses.size();
13569            for (i=0; i<N; i++) {
13570                ProcessRecord app = mLruProcesses.get(i);
13571                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13572                        && app.pendingUiClean) {
13573                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13574                            && app.thread != null) {
13575                        try {
13576                            app.thread.scheduleTrimMemory(
13577                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13578                        } catch (RemoteException e) {
13579                        }
13580                    }
13581                    app.pendingUiClean = false;
13582                }
13583                app.trimMemoryLevel = 0;
13584            }
13585        }
13586
13587        if (mAlwaysFinishActivities) {
13588            // Need to do this on its own message because the stack may not
13589            // be in a consistent state at this point.
13590            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13591        }
13592    }
13593
13594    final void trimApplications() {
13595        synchronized (this) {
13596            int i;
13597
13598            // First remove any unused application processes whose package
13599            // has been removed.
13600            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13601                final ProcessRecord app = mRemovedProcesses.get(i);
13602                if (app.activities.size() == 0
13603                        && app.curReceiver == null && app.services.size() == 0) {
13604                    Slog.i(
13605                        TAG, "Exiting empty application process "
13606                        + app.processName + " ("
13607                        + (app.thread != null ? app.thread.asBinder() : null)
13608                        + ")\n");
13609                    if (app.pid > 0 && app.pid != MY_PID) {
13610                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13611                                app.processName, app.setAdj, "empty");
13612                        Process.killProcessQuiet(app.pid);
13613                    } else {
13614                        try {
13615                            app.thread.scheduleExit();
13616                        } catch (Exception e) {
13617                            // Ignore exceptions.
13618                        }
13619                    }
13620                    cleanUpApplicationRecordLocked(app, false, true, -1);
13621                    mRemovedProcesses.remove(i);
13622
13623                    if (app.persistent) {
13624                        if (app.persistent) {
13625                            addAppLocked(app.info, false);
13626                        }
13627                    }
13628                }
13629            }
13630
13631            // Now update the oom adj for all processes.
13632            updateOomAdjLocked();
13633        }
13634    }
13635
13636    /** This method sends the specified signal to each of the persistent apps */
13637    public void signalPersistentProcesses(int sig) throws RemoteException {
13638        if (sig != Process.SIGNAL_USR1) {
13639            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13640        }
13641
13642        synchronized (this) {
13643            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13644                    != PackageManager.PERMISSION_GRANTED) {
13645                throw new SecurityException("Requires permission "
13646                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13647            }
13648
13649            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13650                ProcessRecord r = mLruProcesses.get(i);
13651                if (r.thread != null && r.persistent) {
13652                    Process.sendSignal(r.pid, sig);
13653                }
13654            }
13655        }
13656    }
13657
13658    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13659        if (proc == null || proc == mProfileProc) {
13660            proc = mProfileProc;
13661            path = mProfileFile;
13662            profileType = mProfileType;
13663            clearProfilerLocked();
13664        }
13665        if (proc == null) {
13666            return;
13667        }
13668        try {
13669            proc.thread.profilerControl(false, path, null, profileType);
13670        } catch (RemoteException e) {
13671            throw new IllegalStateException("Process disappeared");
13672        }
13673    }
13674
13675    private void clearProfilerLocked() {
13676        if (mProfileFd != null) {
13677            try {
13678                mProfileFd.close();
13679            } catch (IOException e) {
13680            }
13681        }
13682        mProfileApp = null;
13683        mProfileProc = null;
13684        mProfileFile = null;
13685        mProfileType = 0;
13686        mAutoStopProfiler = false;
13687    }
13688
13689    public boolean profileControl(String process, boolean start,
13690            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13691
13692        try {
13693            synchronized (this) {
13694                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13695                // its own permission.
13696                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13697                        != PackageManager.PERMISSION_GRANTED) {
13698                    throw new SecurityException("Requires permission "
13699                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13700                }
13701
13702                if (start && fd == null) {
13703                    throw new IllegalArgumentException("null fd");
13704                }
13705
13706                ProcessRecord proc = null;
13707                if (process != null) {
13708                    try {
13709                        int pid = Integer.parseInt(process);
13710                        synchronized (mPidsSelfLocked) {
13711                            proc = mPidsSelfLocked.get(pid);
13712                        }
13713                    } catch (NumberFormatException e) {
13714                    }
13715
13716                    if (proc == null) {
13717                        HashMap<String, SparseArray<ProcessRecord>> all
13718                                = mProcessNames.getMap();
13719                        SparseArray<ProcessRecord> procs = all.get(process);
13720                        if (procs != null && procs.size() > 0) {
13721                            proc = procs.valueAt(0);
13722                        }
13723                    }
13724                }
13725
13726                if (start && (proc == null || proc.thread == null)) {
13727                    throw new IllegalArgumentException("Unknown process: " + process);
13728                }
13729
13730                if (start) {
13731                    stopProfilerLocked(null, null, 0);
13732                    setProfileApp(proc.info, proc.processName, path, fd, false);
13733                    mProfileProc = proc;
13734                    mProfileType = profileType;
13735                    try {
13736                        fd = fd.dup();
13737                    } catch (IOException e) {
13738                        fd = null;
13739                    }
13740                    proc.thread.profilerControl(start, path, fd, profileType);
13741                    fd = null;
13742                    mProfileFd = null;
13743                } else {
13744                    stopProfilerLocked(proc, path, profileType);
13745                    if (fd != null) {
13746                        try {
13747                            fd.close();
13748                        } catch (IOException e) {
13749                        }
13750                    }
13751                }
13752
13753                return true;
13754            }
13755        } catch (RemoteException e) {
13756            throw new IllegalStateException("Process disappeared");
13757        } finally {
13758            if (fd != null) {
13759                try {
13760                    fd.close();
13761                } catch (IOException e) {
13762                }
13763            }
13764        }
13765    }
13766
13767    public boolean dumpHeap(String process, boolean managed,
13768            String path, ParcelFileDescriptor fd) throws RemoteException {
13769
13770        try {
13771            synchronized (this) {
13772                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13773                // its own permission (same as profileControl).
13774                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13775                        != PackageManager.PERMISSION_GRANTED) {
13776                    throw new SecurityException("Requires permission "
13777                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13778                }
13779
13780                if (fd == null) {
13781                    throw new IllegalArgumentException("null fd");
13782                }
13783
13784                ProcessRecord proc = null;
13785                try {
13786                    int pid = Integer.parseInt(process);
13787                    synchronized (mPidsSelfLocked) {
13788                        proc = mPidsSelfLocked.get(pid);
13789                    }
13790                } catch (NumberFormatException e) {
13791                }
13792
13793                if (proc == null) {
13794                    HashMap<String, SparseArray<ProcessRecord>> all
13795                            = mProcessNames.getMap();
13796                    SparseArray<ProcessRecord> procs = all.get(process);
13797                    if (procs != null && procs.size() > 0) {
13798                        proc = procs.valueAt(0);
13799                    }
13800                }
13801
13802                if (proc == null || proc.thread == null) {
13803                    throw new IllegalArgumentException("Unknown process: " + process);
13804                }
13805
13806                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13807                if (!isDebuggable) {
13808                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13809                        throw new SecurityException("Process not debuggable: " + proc);
13810                    }
13811                }
13812
13813                proc.thread.dumpHeap(managed, path, fd);
13814                fd = null;
13815                return true;
13816            }
13817        } catch (RemoteException e) {
13818            throw new IllegalStateException("Process disappeared");
13819        } finally {
13820            if (fd != null) {
13821                try {
13822                    fd.close();
13823                } catch (IOException e) {
13824                }
13825            }
13826        }
13827    }
13828
13829    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13830    public void monitor() {
13831        synchronized (this) { }
13832    }
13833
13834    void onCoreSettingsChange(Bundle settings) {
13835        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13836            ProcessRecord processRecord = mLruProcesses.get(i);
13837            try {
13838                if (processRecord.thread != null) {
13839                    processRecord.thread.setCoreSettings(settings);
13840                }
13841            } catch (RemoteException re) {
13842                /* ignore */
13843            }
13844        }
13845    }
13846
13847    // Multi-user methods
13848
13849    @Override
13850    public boolean switchUser(int userId) {
13851        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13852                != PackageManager.PERMISSION_GRANTED) {
13853            String msg = "Permission Denial: switchUser() from pid="
13854                    + Binder.getCallingPid()
13855                    + ", uid=" + Binder.getCallingUid()
13856                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13857            Slog.w(TAG, msg);
13858            throw new SecurityException(msg);
13859        }
13860        synchronized (this) {
13861            if (mCurrentUserId == userId) {
13862                return true;
13863            }
13864
13865            // If the user we are switching to is not currently started, then
13866            // we need to start it now.
13867            if (mStartedUsers.get(userId) == null) {
13868                mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
13869            }
13870
13871            mCurrentUserId = userId;
13872            Integer userIdInt = Integer.valueOf(userId);
13873            mUserLru.remove(userIdInt);
13874            mUserLru.add(userIdInt);
13875            boolean haveActivities = mMainStack.switchUser(userId);
13876            if (!haveActivities) {
13877                startHomeActivityLocked(userId, mStartedUsers.get(userId));
13878            }
13879        }
13880
13881        long ident = Binder.clearCallingIdentity();
13882        try {
13883            // Inform of user switch
13884            Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
13885            addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13886            mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL,
13887                    android.Manifest.permission.MANAGE_USERS);
13888        } finally {
13889            Binder.restoreCallingIdentity(ident);
13890        }
13891
13892        return true;
13893    }
13894
13895    void finishUserSwitch(UserStartedState uss) {
13896        synchronized (this) {
13897            if (uss.mState == UserStartedState.STATE_BOOTING
13898                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
13899                uss.mState = UserStartedState.STATE_RUNNING;
13900                final int userId = uss.mHandle.getIdentifier();
13901                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
13902                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13903                broadcastIntentLocked(null, null, intent,
13904                        null, null, 0, null, null,
13905                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
13906                        false, false, MY_PID, Process.SYSTEM_UID, userId);
13907            }
13908        }
13909    }
13910
13911    @Override
13912    public int stopUser(final int userId, final IStopUserCallback callback) {
13913        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13914                != PackageManager.PERMISSION_GRANTED) {
13915            String msg = "Permission Denial: switchUser() from pid="
13916                    + Binder.getCallingPid()
13917                    + ", uid=" + Binder.getCallingUid()
13918                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13919            Slog.w(TAG, msg);
13920            throw new SecurityException(msg);
13921        }
13922        if (userId <= 0) {
13923            throw new IllegalArgumentException("Can't stop primary user " + userId);
13924        }
13925        synchronized (this) {
13926            if (mCurrentUserId == userId) {
13927                return ActivityManager.USER_OP_IS_CURRENT;
13928            }
13929
13930            final UserStartedState uss = mStartedUsers.get(userId);
13931            if (uss == null) {
13932                // User is not started, nothing to do...  but we do need to
13933                // callback if requested.
13934                if (callback != null) {
13935                    mHandler.post(new Runnable() {
13936                        @Override
13937                        public void run() {
13938                            try {
13939                                callback.userStopped(userId);
13940                            } catch (RemoteException e) {
13941                            }
13942                        }
13943                    });
13944                }
13945                return ActivityManager.USER_OP_SUCCESS;
13946            }
13947
13948            if (callback != null) {
13949                uss.mStopCallbacks.add(callback);
13950            }
13951
13952            if (uss.mState != UserStartedState.STATE_STOPPING) {
13953                uss.mState = UserStartedState.STATE_STOPPING;
13954
13955                long ident = Binder.clearCallingIdentity();
13956                try {
13957                    // Inform of user switch
13958                    Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13959                    final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() {
13960                        @Override
13961                        public void performReceive(Intent intent, int resultCode, String data,
13962                                Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
13963                            finishUserStop(uss);
13964                        }
13965                    };
13966                    broadcastIntentLocked(null, null, intent,
13967                            null, resultReceiver, 0, null, null, null,
13968                            true, false, MY_PID, Process.SYSTEM_UID, userId);
13969                } finally {
13970                    Binder.restoreCallingIdentity(ident);
13971                }
13972            }
13973        }
13974
13975        return ActivityManager.USER_OP_SUCCESS;
13976    }
13977
13978    void finishUserStop(UserStartedState uss) {
13979        final int userId = uss.mHandle.getIdentifier();
13980        boolean stopped;
13981        ArrayList<IStopUserCallback> callbacks;
13982        synchronized (this) {
13983            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
13984            if (uss.mState != UserStartedState.STATE_STOPPING
13985                    || mStartedUsers.get(userId) != uss) {
13986                stopped = false;
13987            } else {
13988                stopped = true;
13989                // User can no longer run.
13990                mStartedUsers.remove(userId);
13991
13992                // Clean up all state and processes associated with the user.
13993                // Kill all the processes for the user.
13994                forceStopUserLocked(userId);
13995            }
13996        }
13997
13998        for (int i=0; i<callbacks.size(); i++) {
13999            try {
14000                if (stopped) callbacks.get(i).userStopped(userId);
14001                else callbacks.get(i).userStopAborted(userId);
14002            } catch (RemoteException e) {
14003            }
14004        }
14005    }
14006
14007    @Override
14008    public UserInfo getCurrentUser() {
14009        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14010                != PackageManager.PERMISSION_GRANTED) {
14011            String msg = "Permission Denial: getCurrentUser() from pid="
14012                    + Binder.getCallingPid()
14013                    + ", uid=" + Binder.getCallingUid()
14014                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14015            Slog.w(TAG, msg);
14016            throw new SecurityException(msg);
14017        }
14018        synchronized (this) {
14019            return getUserManager().getUserInfo(mCurrentUserId);
14020        }
14021    }
14022
14023    @Override
14024    public boolean isUserRunning(int userId) {
14025        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14026                != PackageManager.PERMISSION_GRANTED) {
14027            String msg = "Permission Denial: isUserRunning() from pid="
14028                    + Binder.getCallingPid()
14029                    + ", uid=" + Binder.getCallingUid()
14030                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14031            Slog.w(TAG, msg);
14032            throw new SecurityException(msg);
14033        }
14034        synchronized (this) {
14035            UserStartedState state = mStartedUsers.get(userId);
14036            return state != null && state.mState != UserStartedState.STATE_STOPPING;
14037        }
14038    }
14039
14040    private boolean userExists(int userId) {
14041        UserInfo user = getUserManager().getUserInfo(userId);
14042        return user != null;
14043    }
14044
14045    UserManager getUserManager() {
14046        if (mUserManager == null) {
14047            mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
14048        }
14049        return mUserManager;
14050    }
14051
14052    private void checkValidCaller(int uid, int userId) {
14053        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
14054
14055        throw new SecurityException("Caller uid=" + uid
14056                + " is not privileged to communicate with user=" + userId);
14057    }
14058
14059    private int applyUserId(int uid, int userId) {
14060        return UserHandle.getUid(userId, uid);
14061    }
14062
14063    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
14064        if (info == null) return null;
14065        ApplicationInfo newInfo = new ApplicationInfo(info);
14066        newInfo.uid = applyUserId(info.uid, userId);
14067        newInfo.dataDir = USER_DATA_DIR + userId + "/"
14068                + info.packageName;
14069        return newInfo;
14070    }
14071
14072    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
14073        if (aInfo == null
14074                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
14075            return aInfo;
14076        }
14077
14078        ActivityInfo info = new ActivityInfo(aInfo);
14079        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
14080        return info;
14081    }
14082}
14083