ActivityManagerService.java revision 0068d3dcf1f1a804554a1a09e3b173ac12651786
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.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.IActivityContainer;
37import android.app.IActivityContainerCallback;
38import android.app.IAppTask;
39import android.app.admin.DevicePolicyManager;
40import android.app.usage.UsageStats;
41import android.app.usage.UsageStatsManagerInternal;
42import android.appwidget.AppWidgetManager;
43import android.graphics.Rect;
44import android.os.BatteryStats;
45import android.os.PersistableBundle;
46import android.service.voice.IVoiceInteractionSession;
47import android.util.ArrayMap;
48import android.util.ArraySet;
49import android.util.SparseIntArray;
50
51import com.android.internal.R;
52import com.android.internal.annotations.GuardedBy;
53import com.android.internal.app.IAppOpsService;
54import com.android.internal.app.IVoiceInteractor;
55import com.android.internal.app.ProcessMap;
56import com.android.internal.app.ProcessStats;
57import com.android.internal.content.PackageMonitor;
58import com.android.internal.os.BackgroundThread;
59import com.android.internal.os.BatteryStatsImpl;
60import com.android.internal.os.ProcessCpuTracker;
61import com.android.internal.os.TransferPipe;
62import com.android.internal.os.Zygote;
63import com.android.internal.util.FastPrintWriter;
64import com.android.internal.util.FastXmlSerializer;
65import com.android.internal.util.MemInfoReader;
66import com.android.internal.util.Preconditions;
67import com.android.server.AppOpsService;
68import com.android.server.AttributeCache;
69import com.android.server.IntentResolver;
70import com.android.server.LocalServices;
71import com.android.server.ServiceThread;
72import com.android.server.SystemService;
73import com.android.server.SystemServiceManager;
74import com.android.server.Watchdog;
75import com.android.server.am.ActivityStack.ActivityState;
76import com.android.server.firewall.IntentFirewall;
77import com.android.server.pm.UserManagerService;
78import com.android.server.wm.AppTransition;
79import com.android.server.wm.WindowManagerService;
80import com.google.android.collect.Lists;
81import com.google.android.collect.Maps;
82
83import libcore.io.IoUtils;
84
85import org.xmlpull.v1.XmlPullParser;
86import org.xmlpull.v1.XmlPullParserException;
87import org.xmlpull.v1.XmlSerializer;
88
89import android.app.Activity;
90import android.app.ActivityManager;
91import android.app.ActivityManager.RunningTaskInfo;
92import android.app.ActivityManager.StackInfo;
93import android.app.ActivityManagerInternal;
94import android.app.ActivityManagerNative;
95import android.app.ActivityOptions;
96import android.app.ActivityThread;
97import android.app.AlertDialog;
98import android.app.AppGlobals;
99import android.app.ApplicationErrorReport;
100import android.app.Dialog;
101import android.app.IActivityController;
102import android.app.IApplicationThread;
103import android.app.IInstrumentationWatcher;
104import android.app.INotificationManager;
105import android.app.IProcessObserver;
106import android.app.IServiceConnection;
107import android.app.IStopUserCallback;
108import android.app.IUiAutomationConnection;
109import android.app.IUserSwitchObserver;
110import android.app.Instrumentation;
111import android.app.Notification;
112import android.app.NotificationManager;
113import android.app.PendingIntent;
114import android.app.backup.IBackupManager;
115import android.content.ActivityNotFoundException;
116import android.content.BroadcastReceiver;
117import android.content.ClipData;
118import android.content.ComponentCallbacks2;
119import android.content.ComponentName;
120import android.content.ContentProvider;
121import android.content.ContentResolver;
122import android.content.Context;
123import android.content.DialogInterface;
124import android.content.IContentProvider;
125import android.content.IIntentReceiver;
126import android.content.IIntentSender;
127import android.content.Intent;
128import android.content.IntentFilter;
129import android.content.IntentSender;
130import android.content.pm.ActivityInfo;
131import android.content.pm.ApplicationInfo;
132import android.content.pm.ConfigurationInfo;
133import android.content.pm.IPackageDataObserver;
134import android.content.pm.IPackageManager;
135import android.content.pm.InstrumentationInfo;
136import android.content.pm.PackageInfo;
137import android.content.pm.PackageManager;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.UserInfo;
140import android.content.pm.PackageManager.NameNotFoundException;
141import android.content.pm.PathPermission;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.net.Proxy;
148import android.net.ProxyInfo;
149import android.net.Uri;
150import android.os.Binder;
151import android.os.Build;
152import android.os.Bundle;
153import android.os.Debug;
154import android.os.DropBoxManager;
155import android.os.Environment;
156import android.os.FactoryTest;
157import android.os.FileObserver;
158import android.os.FileUtils;
159import android.os.Handler;
160import android.os.IBinder;
161import android.os.IPermissionController;
162import android.os.IRemoteCallback;
163import android.os.IUserManager;
164import android.os.Looper;
165import android.os.Message;
166import android.os.Parcel;
167import android.os.ParcelFileDescriptor;
168import android.os.Process;
169import android.os.RemoteCallbackList;
170import android.os.RemoteException;
171import android.os.SELinux;
172import android.os.ServiceManager;
173import android.os.StrictMode;
174import android.os.SystemClock;
175import android.os.SystemProperties;
176import android.os.UpdateLock;
177import android.os.UserHandle;
178import android.provider.Settings;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.util.AtomicFile;
182import android.util.EventLog;
183import android.util.Log;
184import android.util.Pair;
185import android.util.PrintWriterPrinter;
186import android.util.Slog;
187import android.util.SparseArray;
188import android.util.TimeUtils;
189import android.util.Xml;
190import android.view.Gravity;
191import android.view.LayoutInflater;
192import android.view.View;
193import android.view.WindowManager;
194
195import java.io.BufferedInputStream;
196import java.io.BufferedOutputStream;
197import java.io.DataInputStream;
198import java.io.DataOutputStream;
199import java.io.File;
200import java.io.FileDescriptor;
201import java.io.FileInputStream;
202import java.io.FileNotFoundException;
203import java.io.FileOutputStream;
204import java.io.IOException;
205import java.io.InputStreamReader;
206import java.io.PrintWriter;
207import java.io.StringWriter;
208import java.lang.ref.WeakReference;
209import java.util.ArrayList;
210import java.util.Arrays;
211import java.util.Collections;
212import java.util.Comparator;
213import java.util.HashMap;
214import java.util.HashSet;
215import java.util.Iterator;
216import java.util.List;
217import java.util.Locale;
218import java.util.Map;
219import java.util.Set;
220import java.util.concurrent.atomic.AtomicBoolean;
221import java.util.concurrent.atomic.AtomicLong;
222
223public final class ActivityManagerService extends ActivityManagerNative
224        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
225
226    private static final String USER_DATA_DIR = "/data/user/";
227    // File that stores last updated system version and called preboot receivers
228    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
229
230    static final String TAG = "ActivityManager";
231    static final String TAG_MU = "ActivityManagerServiceMU";
232    static final boolean DEBUG = false;
233    static final boolean localLOGV = DEBUG;
234    static final boolean DEBUG_BACKUP = localLOGV || false;
235    static final boolean DEBUG_BROADCAST = localLOGV || false;
236    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
237    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
238    static final boolean DEBUG_CLEANUP = localLOGV || false;
239    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
240    static final boolean DEBUG_FOCUS = false;
241    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
242    static final boolean DEBUG_MU = localLOGV || false;
243    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
244    static final boolean DEBUG_LRU = localLOGV || false;
245    static final boolean DEBUG_PAUSE = localLOGV || false;
246    static final boolean DEBUG_POWER = localLOGV || false;
247    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
248    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
249    static final boolean DEBUG_PROCESSES = localLOGV || false;
250    static final boolean DEBUG_PROVIDER = localLOGV || false;
251    static final boolean DEBUG_RESULTS = localLOGV || false;
252    static final boolean DEBUG_SERVICE = localLOGV || false;
253    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
254    static final boolean DEBUG_STACK = localLOGV || false;
255    static final boolean DEBUG_SWITCH = localLOGV || false;
256    static final boolean DEBUG_TASKS = localLOGV || false;
257    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
258    static final boolean DEBUG_TRANSITION = localLOGV || false;
259    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
260    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
261    static final boolean DEBUG_VISBILITY = localLOGV || false;
262    static final boolean DEBUG_PSS = localLOGV || false;
263    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
264    static final boolean VALIDATE_TOKENS = false;
265    static final boolean SHOW_ACTIVITY_START_TIME = true;
266
267    // Control over CPU and battery monitoring.
268    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
269    static final boolean MONITOR_CPU_USAGE = true;
270    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
271    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
272    static final boolean MONITOR_THREAD_CPU_USAGE = false;
273
274    // The flags that are set for all calls we make to the package manager.
275    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
276
277    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
278
279    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
280
281    // Maximum number of recent tasks that we can remember.
282    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
283
284    // Maximum number recent bitmaps to keep in memory.
285    static final int MAX_RECENT_BITMAPS = 5;
286
287    // Amount of time after a call to stopAppSwitches() during which we will
288    // prevent further untrusted switches from happening.
289    static final long APP_SWITCH_DELAY_TIME = 5*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real.
293    static final int PROC_START_TIMEOUT = 10*1000;
294
295    // How long we wait for a launched process to attach to the activity manager
296    // before we decide it's never going to come up for real, when the process was
297    // started with a wrapper for instrumentation (such as Valgrind) because it
298    // could take much longer than usual.
299    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
300
301    // How long to wait after going idle before forcing apps to GC.
302    static final int GC_TIMEOUT = 5*1000;
303
304    // The minimum amount of time between successive GC requests for a process.
305    static final int GC_MIN_INTERVAL = 60*1000;
306
307    // The minimum amount of time between successive PSS requests for a process.
308    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
309
310    // The minimum amount of time between successive PSS requests for a process
311    // when the request is due to the memory state being lowered.
312    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
313
314    // The rate at which we check for apps using excessive power -- 15 mins.
315    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on wake locks to start killing things.
319    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on CPU usage to start killing things.
323    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // How long we allow a receiver to run before giving up on it.
326    static final int BROADCAST_FG_TIMEOUT = 10*1000;
327    static final int BROADCAST_BG_TIMEOUT = 60*1000;
328
329    // How long we wait until we timeout on key dispatching.
330    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
331
332    // How long we wait until we timeout on key dispatching during instrumentation.
333    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
334
335    // Amount of time we wait for observers to handle a user switch before
336    // giving up on them and unfreezing the screen.
337    static final int USER_SWITCH_TIMEOUT = 2*1000;
338
339    // Maximum number of users we allow to be running at a time.
340    static final int MAX_RUNNING_USERS = 3;
341
342    // How long to wait in getAssistContextExtras for the activity and foreground services
343    // to respond with the result.
344    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
345
346    // Maximum number of persisted Uri grants a package is allowed
347    static final int MAX_PERSISTED_URI_GRANTS = 128;
348
349    static final int MY_PID = Process.myPid();
350
351    static final String[] EMPTY_STRING_ARRAY = new String[0];
352
353    // How many bytes to write into the dropbox log before truncating
354    static final int DROPBOX_MAX_SIZE = 256 * 1024;
355
356    // Access modes for handleIncomingUser.
357    static final int ALLOW_NON_FULL = 0;
358    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
359    static final int ALLOW_FULL_ONLY = 2;
360
361    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
362
363    /** All system services */
364    SystemServiceManager mSystemServiceManager;
365
366    /** Run all ActivityStacks through this */
367    ActivityStackSupervisor mStackSupervisor;
368
369    public IntentFirewall mIntentFirewall;
370
371    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
372    // default actuion automatically.  Important for devices without direct input
373    // devices.
374    private boolean mShowDialogs = true;
375
376    BroadcastQueue mFgBroadcastQueue;
377    BroadcastQueue mBgBroadcastQueue;
378    // Convenient for easy iteration over the queues. Foreground is first
379    // so that dispatch of foreground broadcasts gets precedence.
380    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
381
382    BroadcastQueue broadcastQueueForIntent(Intent intent) {
383        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
384        if (DEBUG_BACKGROUND_BROADCAST) {
385            Slog.i(TAG, "Broadcast intent " + intent + " on "
386                    + (isFg ? "foreground" : "background")
387                    + " queue");
388        }
389        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
390    }
391
392    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
393        for (BroadcastQueue queue : mBroadcastQueues) {
394            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
395            if (r != null) {
396                return r;
397            }
398        }
399        return null;
400    }
401
402    /**
403     * Activity we have told the window manager to have key focus.
404     */
405    ActivityRecord mFocusedActivity = null;
406
407    /**
408     * List of intents that were used to start the most recent tasks.
409     */
410    ArrayList<TaskRecord> mRecentTasks;
411    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
412
413    public class PendingAssistExtras extends Binder implements Runnable {
414        public final ActivityRecord activity;
415        public boolean haveResult = false;
416        public Bundle result = null;
417        public PendingAssistExtras(ActivityRecord _activity) {
418            activity = _activity;
419        }
420        @Override
421        public void run() {
422            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
423            synchronized (this) {
424                haveResult = true;
425                notifyAll();
426            }
427        }
428    }
429
430    final ArrayList<PendingAssistExtras> mPendingAssistExtras
431            = new ArrayList<PendingAssistExtras>();
432
433    /**
434     * Process management.
435     */
436    final ProcessList mProcessList = new ProcessList();
437
438    /**
439     * All of the applications we currently have running organized by name.
440     * The keys are strings of the application package name (as
441     * returned by the package manager), and the keys are ApplicationRecord
442     * objects.
443     */
444    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
445
446    /**
447     * Tracking long-term execution of processes to look for abuse and other
448     * bad app behavior.
449     */
450    final ProcessStatsService mProcessStats;
451
452    /**
453     * The currently running isolated processes.
454     */
455    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
456
457    /**
458     * Counter for assigning isolated process uids, to avoid frequently reusing the
459     * same ones.
460     */
461    int mNextIsolatedProcessUid = 0;
462
463    /**
464     * The currently running heavy-weight process, if any.
465     */
466    ProcessRecord mHeavyWeightProcess = null;
467
468    /**
469     * The last time that various processes have crashed.
470     */
471    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
472
473    /**
474     * Information about a process that is currently marked as bad.
475     */
476    static final class BadProcessInfo {
477        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
478            this.time = time;
479            this.shortMsg = shortMsg;
480            this.longMsg = longMsg;
481            this.stack = stack;
482        }
483
484        final long time;
485        final String shortMsg;
486        final String longMsg;
487        final String stack;
488    }
489
490    /**
491     * Set of applications that we consider to be bad, and will reject
492     * incoming broadcasts from (which the user has no control over).
493     * Processes are added to this set when they have crashed twice within
494     * a minimum amount of time; they are removed from it when they are
495     * later restarted (hopefully due to some user action).  The value is the
496     * time it was added to the list.
497     */
498    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
499
500    /**
501     * All of the processes we currently have running organized by pid.
502     * The keys are the pid running the application.
503     *
504     * <p>NOTE: This object is protected by its own lock, NOT the global
505     * activity manager lock!
506     */
507    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
508
509    /**
510     * All of the processes that have been forced to be foreground.  The key
511     * is the pid of the caller who requested it (we hold a death
512     * link on it).
513     */
514    abstract class ForegroundToken implements IBinder.DeathRecipient {
515        int pid;
516        IBinder token;
517    }
518    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
519
520    /**
521     * List of records for processes that someone had tried to start before the
522     * system was ready.  We don't start them at that point, but ensure they
523     * are started by the time booting is complete.
524     */
525    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of persistent applications that are in the process
529     * of being started.
530     */
531    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Processes that are being forcibly torn down.
535     */
536    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * List of running applications, sorted by recent usage.
540     * The first entry in the list is the least recently used.
541     */
542    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
543
544    /**
545     * Where in mLruProcesses that the processes hosting activities start.
546     */
547    int mLruProcessActivityStart = 0;
548
549    /**
550     * Where in mLruProcesses that the processes hosting services start.
551     * This is after (lower index) than mLruProcessesActivityStart.
552     */
553    int mLruProcessServiceStart = 0;
554
555    /**
556     * List of processes that should gc as soon as things are idle.
557     */
558    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
559
560    /**
561     * Processes we want to collect PSS data from.
562     */
563    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Last time we requested PSS data of all processes.
567     */
568    long mLastFullPssTime = SystemClock.uptimeMillis();
569
570    /**
571     * If set, the next time we collect PSS data we should do a full collection
572     * with data from native processes and the kernel.
573     */
574    boolean mFullPssPending = false;
575
576    /**
577     * This is the process holding what we currently consider to be
578     * the "home" activity.
579     */
580    ProcessRecord mHomeProcess;
581
582    /**
583     * This is the process holding the activity the user last visited that
584     * is in a different process from the one they are currently in.
585     */
586    ProcessRecord mPreviousProcess;
587
588    /**
589     * The time at which the previous process was last visible.
590     */
591    long mPreviousProcessVisibleTime;
592
593    /**
594     * Which uses have been started, so are allowed to run code.
595     */
596    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
597
598    /**
599     * LRU list of history of current users.  Most recently current is at the end.
600     */
601    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
602
603    /**
604     * Constant array of the users that are currently started.
605     */
606    int[] mStartedUserArray = new int[] { 0 };
607
608    /**
609     * Registered observers of the user switching mechanics.
610     */
611    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
612            = new RemoteCallbackList<IUserSwitchObserver>();
613
614    /**
615     * Currently active user switch.
616     */
617    Object mCurUserSwitchCallback;
618
619    /**
620     * Packages that the user has asked to have run in screen size
621     * compatibility mode instead of filling the screen.
622     */
623    final CompatModePackages mCompatModePackages;
624
625    /**
626     * Set of IntentSenderRecord objects that are currently active.
627     */
628    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
629            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
630
631    /**
632     * Fingerprints (hashCode()) of stack traces that we've
633     * already logged DropBox entries for.  Guarded by itself.  If
634     * something (rogue user app) forces this over
635     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
636     */
637    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
638    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
639
640    /**
641     * Strict Mode background batched logging state.
642     *
643     * The string buffer is guarded by itself, and its lock is also
644     * used to determine if another batched write is already
645     * in-flight.
646     */
647    private final StringBuilder mStrictModeBuffer = new StringBuilder();
648
649    /**
650     * Keeps track of all IIntentReceivers that have been registered for
651     * broadcasts.  Hash keys are the receiver IBinder, hash value is
652     * a ReceiverList.
653     */
654    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
655            new HashMap<IBinder, ReceiverList>();
656
657    /**
658     * Resolver for broadcast intents to registered receivers.
659     * Holds BroadcastFilter (subclass of IntentFilter).
660     */
661    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
662            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
663        @Override
664        protected boolean allowFilterResult(
665                BroadcastFilter filter, List<BroadcastFilter> dest) {
666            IBinder target = filter.receiverList.receiver.asBinder();
667            for (int i=dest.size()-1; i>=0; i--) {
668                if (dest.get(i).receiverList.receiver.asBinder() == target) {
669                    return false;
670                }
671            }
672            return true;
673        }
674
675        @Override
676        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
677            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
678                    || userId == filter.owningUserId) {
679                return super.newResult(filter, match, userId);
680            }
681            return null;
682        }
683
684        @Override
685        protected BroadcastFilter[] newArray(int size) {
686            return new BroadcastFilter[size];
687        }
688
689        @Override
690        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
691            return packageName.equals(filter.packageName);
692        }
693    };
694
695    /**
696     * State of all active sticky broadcasts per user.  Keys are the action of the
697     * sticky Intent, values are an ArrayList of all broadcasted intents with
698     * that action (which should usually be one).  The SparseArray is keyed
699     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
700     * for stickies that are sent to all users.
701     */
702    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
703            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
704
705    final ActiveServices mServices;
706
707    /**
708     * Backup/restore process management
709     */
710    String mBackupAppName = null;
711    BackupRecord mBackupTarget = null;
712
713    final ProviderMap mProviderMap;
714
715    /**
716     * List of content providers who have clients waiting for them.  The
717     * application is currently being launched and the provider will be
718     * removed from this list once it is published.
719     */
720    final ArrayList<ContentProviderRecord> mLaunchingProviders
721            = new ArrayList<ContentProviderRecord>();
722
723    /**
724     * File storing persisted {@link #mGrantedUriPermissions}.
725     */
726    private final AtomicFile mGrantFile;
727
728    /** XML constants used in {@link #mGrantFile} */
729    private static final String TAG_URI_GRANTS = "uri-grants";
730    private static final String TAG_URI_GRANT = "uri-grant";
731    private static final String ATTR_USER_HANDLE = "userHandle";
732    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
733    private static final String ATTR_TARGET_USER_ID = "targetUserId";
734    private static final String ATTR_SOURCE_PKG = "sourcePkg";
735    private static final String ATTR_TARGET_PKG = "targetPkg";
736    private static final String ATTR_URI = "uri";
737    private static final String ATTR_MODE_FLAGS = "modeFlags";
738    private static final String ATTR_CREATED_TIME = "createdTime";
739    private static final String ATTR_PREFIX = "prefix";
740
741    /**
742     * Global set of specific {@link Uri} permissions that have been granted.
743     * This optimized lookup structure maps from {@link UriPermission#targetUid}
744     * to {@link UriPermission#uri} to {@link UriPermission}.
745     */
746    @GuardedBy("this")
747    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
748            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
749
750    public static class GrantUri {
751        public final int sourceUserId;
752        public final Uri uri;
753        public boolean prefix;
754
755        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
756            this.sourceUserId = sourceUserId;
757            this.uri = uri;
758            this.prefix = prefix;
759        }
760
761        @Override
762        public int hashCode() {
763            return toString().hashCode();
764        }
765
766        @Override
767        public boolean equals(Object o) {
768            if (o instanceof GrantUri) {
769                GrantUri other = (GrantUri) o;
770                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
771                        && prefix == other.prefix;
772            }
773            return false;
774        }
775
776        @Override
777        public String toString() {
778            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
779            if (prefix) result += " [prefix]";
780            return result;
781        }
782
783        public String toSafeString() {
784            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
785            if (prefix) result += " [prefix]";
786            return result;
787        }
788
789        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
790            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
791                    ContentProvider.getUriWithoutUserId(uri), false);
792        }
793    }
794
795    CoreSettingsObserver mCoreSettingsObserver;
796
797    /**
798     * Thread-local storage used to carry caller permissions over through
799     * indirect content-provider access.
800     */
801    private class Identity {
802        public int pid;
803        public int uid;
804
805        Identity(int _pid, int _uid) {
806            pid = _pid;
807            uid = _uid;
808        }
809    }
810
811    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
812
813    /**
814     * All information we have collected about the runtime performance of
815     * any user id that can impact battery performance.
816     */
817    final BatteryStatsService mBatteryStatsService;
818
819    /**
820     * Information about component usage
821     */
822    UsageStatsManagerInternal mUsageStatsService;
823
824    /**
825     * Information about and control over application operations
826     */
827    final AppOpsService mAppOpsService;
828
829    /**
830     * Save recent tasks information across reboots.
831     */
832    final TaskPersister mTaskPersister;
833
834    /**
835     * Current configuration information.  HistoryRecord objects are given
836     * a reference to this object to indicate which configuration they are
837     * currently running in, so this object must be kept immutable.
838     */
839    Configuration mConfiguration = new Configuration();
840
841    /**
842     * Current sequencing integer of the configuration, for skipping old
843     * configurations.
844     */
845    int mConfigurationSeq = 0;
846
847    /**
848     * Hardware-reported OpenGLES version.
849     */
850    final int GL_ES_VERSION;
851
852    /**
853     * List of initialization arguments to pass to all processes when binding applications to them.
854     * For example, references to the commonly used services.
855     */
856    HashMap<String, IBinder> mAppBindArgs;
857
858    /**
859     * Temporary to avoid allocations.  Protected by main lock.
860     */
861    final StringBuilder mStringBuilder = new StringBuilder(256);
862
863    /**
864     * Used to control how we initialize the service.
865     */
866    ComponentName mTopComponent;
867    String mTopAction = Intent.ACTION_MAIN;
868    String mTopData;
869    boolean mProcessesReady = false;
870    boolean mSystemReady = false;
871    boolean mBooting = false;
872    boolean mWaitingUpdate = false;
873    boolean mDidUpdate = false;
874    boolean mOnBattery = false;
875    boolean mLaunchWarningShown = false;
876
877    Context mContext;
878
879    int mFactoryTest;
880
881    boolean mCheckedForSetup;
882
883    /**
884     * The time at which we will allow normal application switches again,
885     * after a call to {@link #stopAppSwitches()}.
886     */
887    long mAppSwitchesAllowedTime;
888
889    /**
890     * This is set to true after the first switch after mAppSwitchesAllowedTime
891     * is set; any switches after that will clear the time.
892     */
893    boolean mDidAppSwitch;
894
895    /**
896     * Last time (in realtime) at which we checked for power usage.
897     */
898    long mLastPowerCheckRealtime;
899
900    /**
901     * Last time (in uptime) at which we checked for power usage.
902     */
903    long mLastPowerCheckUptime;
904
905    /**
906     * Set while we are wanting to sleep, to prevent any
907     * activities from being started/resumed.
908     */
909    private boolean mSleeping = false;
910
911    /**
912     * Set while we are running a voice interaction.  This overrides
913     * sleeping while it is active.
914     */
915    private boolean mRunningVoice = false;
916
917    /**
918     * State of external calls telling us if the device is asleep.
919     */
920    private boolean mWentToSleep = false;
921
922    /**
923     * State of external call telling us if the lock screen is shown.
924     */
925    private boolean mLockScreenShown = false;
926
927    /**
928     * Set if we are shutting down the system, similar to sleeping.
929     */
930    boolean mShuttingDown = false;
931
932    /**
933     * Current sequence id for oom_adj computation traversal.
934     */
935    int mAdjSeq = 0;
936
937    /**
938     * Current sequence id for process LRU updating.
939     */
940    int mLruSeq = 0;
941
942    /**
943     * Keep track of the non-cached/empty process we last found, to help
944     * determine how to distribute cached/empty processes next time.
945     */
946    int mNumNonCachedProcs = 0;
947
948    /**
949     * Keep track of the number of cached hidden procs, to balance oom adj
950     * distribution between those and empty procs.
951     */
952    int mNumCachedHiddenProcs = 0;
953
954    /**
955     * Keep track of the number of service processes we last found, to
956     * determine on the next iteration which should be B services.
957     */
958    int mNumServiceProcs = 0;
959    int mNewNumAServiceProcs = 0;
960    int mNewNumServiceProcs = 0;
961
962    /**
963     * Allow the current computed overall memory level of the system to go down?
964     * This is set to false when we are killing processes for reasons other than
965     * memory management, so that the now smaller process list will not be taken as
966     * an indication that memory is tighter.
967     */
968    boolean mAllowLowerMemLevel = false;
969
970    /**
971     * The last computed memory level, for holding when we are in a state that
972     * processes are going away for other reasons.
973     */
974    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
975
976    /**
977     * The last total number of process we have, to determine if changes actually look
978     * like a shrinking number of process due to lower RAM.
979     */
980    int mLastNumProcesses;
981
982    /**
983     * The uptime of the last time we performed idle maintenance.
984     */
985    long mLastIdleTime = SystemClock.uptimeMillis();
986
987    /**
988     * Total time spent with RAM that has been added in the past since the last idle time.
989     */
990    long mLowRamTimeSinceLastIdle = 0;
991
992    /**
993     * If RAM is currently low, when that horrible situation started.
994     */
995    long mLowRamStartTime = 0;
996
997    /**
998     * For reporting to battery stats the current top application.
999     */
1000    private String mCurResumedPackage = null;
1001    private int mCurResumedUid = -1;
1002
1003    /**
1004     * For reporting to battery stats the apps currently running foreground
1005     * service.  The ProcessMap is package/uid tuples; each of these contain
1006     * an array of the currently foreground processes.
1007     */
1008    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1009            = new ProcessMap<ArrayList<ProcessRecord>>();
1010
1011    /**
1012     * This is set if we had to do a delayed dexopt of an app before launching
1013     * it, to increase the ANR timeouts in that case.
1014     */
1015    boolean mDidDexOpt;
1016
1017    /**
1018     * Set if the systemServer made a call to enterSafeMode.
1019     */
1020    boolean mSafeMode;
1021
1022    String mDebugApp = null;
1023    boolean mWaitForDebugger = false;
1024    boolean mDebugTransient = false;
1025    String mOrigDebugApp = null;
1026    boolean mOrigWaitForDebugger = false;
1027    boolean mAlwaysFinishActivities = false;
1028    IActivityController mController = null;
1029    String mProfileApp = null;
1030    ProcessRecord mProfileProc = null;
1031    String mProfileFile;
1032    ParcelFileDescriptor mProfileFd;
1033    int mProfileType = 0;
1034    boolean mAutoStopProfiler = false;
1035    String mOpenGlTraceApp = null;
1036
1037    static class ProcessChangeItem {
1038        static final int CHANGE_ACTIVITIES = 1<<0;
1039        static final int CHANGE_PROCESS_STATE = 1<<1;
1040        int changes;
1041        int uid;
1042        int pid;
1043        int processState;
1044        boolean foregroundActivities;
1045    }
1046
1047    final RemoteCallbackList<IProcessObserver> mProcessObservers
1048            = new RemoteCallbackList<IProcessObserver>();
1049    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1050
1051    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1052            = new ArrayList<ProcessChangeItem>();
1053    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1054            = new ArrayList<ProcessChangeItem>();
1055
1056    /**
1057     * Runtime CPU use collection thread.  This object's lock is used to
1058     * protect all related state.
1059     */
1060    final Thread mProcessCpuThread;
1061
1062    /**
1063     * Used to collect process stats when showing not responding dialog.
1064     * Protected by mProcessCpuThread.
1065     */
1066    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1067            MONITOR_THREAD_CPU_USAGE);
1068    final AtomicLong mLastCpuTime = new AtomicLong(0);
1069    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1070
1071    long mLastWriteTime = 0;
1072
1073    /**
1074     * Used to retain an update lock when the foreground activity is in
1075     * immersive mode.
1076     */
1077    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1078
1079    /**
1080     * Set to true after the system has finished booting.
1081     */
1082    boolean mBooted = false;
1083
1084    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1085    int mProcessLimitOverride = -1;
1086
1087    WindowManagerService mWindowManager;
1088
1089    final ActivityThread mSystemThread;
1090
1091    int mCurrentUserId = 0;
1092    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1093
1094    /**
1095     * Mapping from each known user ID to the profile group ID it is associated with.
1096     */
1097    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1098
1099    private UserManagerService mUserManager;
1100
1101    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1102        final ProcessRecord mApp;
1103        final int mPid;
1104        final IApplicationThread mAppThread;
1105
1106        AppDeathRecipient(ProcessRecord app, int pid,
1107                IApplicationThread thread) {
1108            if (localLOGV) Slog.v(
1109                TAG, "New death recipient " + this
1110                + " for thread " + thread.asBinder());
1111            mApp = app;
1112            mPid = pid;
1113            mAppThread = thread;
1114        }
1115
1116        @Override
1117        public void binderDied() {
1118            if (localLOGV) Slog.v(
1119                TAG, "Death received in " + this
1120                + " for thread " + mAppThread.asBinder());
1121            synchronized(ActivityManagerService.this) {
1122                appDiedLocked(mApp, mPid, mAppThread);
1123            }
1124        }
1125    }
1126
1127    static final int SHOW_ERROR_MSG = 1;
1128    static final int SHOW_NOT_RESPONDING_MSG = 2;
1129    static final int SHOW_FACTORY_ERROR_MSG = 3;
1130    static final int UPDATE_CONFIGURATION_MSG = 4;
1131    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1132    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1133    static final int SERVICE_TIMEOUT_MSG = 12;
1134    static final int UPDATE_TIME_ZONE = 13;
1135    static final int SHOW_UID_ERROR_MSG = 14;
1136    static final int IM_FEELING_LUCKY_MSG = 15;
1137    static final int PROC_START_TIMEOUT_MSG = 20;
1138    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1139    static final int KILL_APPLICATION_MSG = 22;
1140    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1141    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1142    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1143    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1144    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1145    static final int CLEAR_DNS_CACHE_MSG = 28;
1146    static final int UPDATE_HTTP_PROXY_MSG = 29;
1147    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1148    static final int DISPATCH_PROCESSES_CHANGED = 31;
1149    static final int DISPATCH_PROCESS_DIED = 32;
1150    static final int REPORT_MEM_USAGE_MSG = 33;
1151    static final int REPORT_USER_SWITCH_MSG = 34;
1152    static final int CONTINUE_USER_SWITCH_MSG = 35;
1153    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1154    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1155    static final int PERSIST_URI_GRANTS_MSG = 38;
1156    static final int REQUEST_ALL_PSS_MSG = 39;
1157    static final int START_PROFILES_MSG = 40;
1158    static final int UPDATE_TIME = 41;
1159    static final int SYSTEM_USER_START_MSG = 42;
1160    static final int SYSTEM_USER_CURRENT_MSG = 43;
1161    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1162    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1163
1164    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1165    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1166    static final int FIRST_COMPAT_MODE_MSG = 300;
1167    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1168
1169    AlertDialog mUidAlert;
1170    CompatModeDialog mCompatModeDialog;
1171    long mLastMemUsageReportTime = 0;
1172
1173    private LockToAppRequestDialog mLockToAppRequest;
1174
1175    /**
1176     * Flag whether the current user is a "monkey", i.e. whether
1177     * the UI is driven by a UI automation tool.
1178     */
1179    private boolean mUserIsMonkey;
1180
1181    /** Flag whether the device has a recents UI */
1182    final boolean mHasRecents;
1183
1184    final ServiceThread mHandlerThread;
1185    final MainHandler mHandler;
1186
1187    final class MainHandler extends Handler {
1188        public MainHandler(Looper looper) {
1189            super(looper, null, true);
1190        }
1191
1192        @Override
1193        public void handleMessage(Message msg) {
1194            switch (msg.what) {
1195            case SHOW_ERROR_MSG: {
1196                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1197                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1198                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1199                synchronized (ActivityManagerService.this) {
1200                    ProcessRecord proc = (ProcessRecord)data.get("app");
1201                    AppErrorResult res = (AppErrorResult) data.get("result");
1202                    if (proc != null && proc.crashDialog != null) {
1203                        Slog.e(TAG, "App already has crash dialog: " + proc);
1204                        if (res != null) {
1205                            res.set(0);
1206                        }
1207                        return;
1208                    }
1209                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1210                            >= Process.FIRST_APPLICATION_UID
1211                            && proc.pid != MY_PID);
1212                    for (int userId : mCurrentProfileIds) {
1213                        isBackground &= (proc.userId != userId);
1214                    }
1215                    if (isBackground && !showBackground) {
1216                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1217                        if (res != null) {
1218                            res.set(0);
1219                        }
1220                        return;
1221                    }
1222                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1223                        Dialog d = new AppErrorDialog(mContext,
1224                                ActivityManagerService.this, res, proc);
1225                        d.show();
1226                        proc.crashDialog = d;
1227                    } else {
1228                        // The device is asleep, so just pretend that the user
1229                        // saw a crash dialog and hit "force quit".
1230                        if (res != null) {
1231                            res.set(0);
1232                        }
1233                    }
1234                }
1235
1236                ensureBootCompleted();
1237            } break;
1238            case SHOW_NOT_RESPONDING_MSG: {
1239                synchronized (ActivityManagerService.this) {
1240                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1241                    ProcessRecord proc = (ProcessRecord)data.get("app");
1242                    if (proc != null && proc.anrDialog != null) {
1243                        Slog.e(TAG, "App already has anr dialog: " + proc);
1244                        return;
1245                    }
1246
1247                    Intent intent = new Intent("android.intent.action.ANR");
1248                    if (!mProcessesReady) {
1249                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1250                                | Intent.FLAG_RECEIVER_FOREGROUND);
1251                    }
1252                    broadcastIntentLocked(null, null, intent,
1253                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1254                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1255
1256                    if (mShowDialogs) {
1257                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1258                                mContext, proc, (ActivityRecord)data.get("activity"),
1259                                msg.arg1 != 0);
1260                        d.show();
1261                        proc.anrDialog = d;
1262                    } else {
1263                        // Just kill the app if there is no dialog to be shown.
1264                        killAppAtUsersRequest(proc, null);
1265                    }
1266                }
1267
1268                ensureBootCompleted();
1269            } break;
1270            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1271                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1272                synchronized (ActivityManagerService.this) {
1273                    ProcessRecord proc = (ProcessRecord) data.get("app");
1274                    if (proc == null) {
1275                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1276                        break;
1277                    }
1278                    if (proc.crashDialog != null) {
1279                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1280                        return;
1281                    }
1282                    AppErrorResult res = (AppErrorResult) data.get("result");
1283                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1284                        Dialog d = new StrictModeViolationDialog(mContext,
1285                                ActivityManagerService.this, res, proc);
1286                        d.show();
1287                        proc.crashDialog = d;
1288                    } else {
1289                        // The device is asleep, so just pretend that the user
1290                        // saw a crash dialog and hit "force quit".
1291                        res.set(0);
1292                    }
1293                }
1294                ensureBootCompleted();
1295            } break;
1296            case SHOW_FACTORY_ERROR_MSG: {
1297                Dialog d = new FactoryErrorDialog(
1298                    mContext, msg.getData().getCharSequence("msg"));
1299                d.show();
1300                ensureBootCompleted();
1301            } break;
1302            case UPDATE_CONFIGURATION_MSG: {
1303                final ContentResolver resolver = mContext.getContentResolver();
1304                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1305            } break;
1306            case GC_BACKGROUND_PROCESSES_MSG: {
1307                synchronized (ActivityManagerService.this) {
1308                    performAppGcsIfAppropriateLocked();
1309                }
1310            } break;
1311            case WAIT_FOR_DEBUGGER_MSG: {
1312                synchronized (ActivityManagerService.this) {
1313                    ProcessRecord app = (ProcessRecord)msg.obj;
1314                    if (msg.arg1 != 0) {
1315                        if (!app.waitedForDebugger) {
1316                            Dialog d = new AppWaitingForDebuggerDialog(
1317                                    ActivityManagerService.this,
1318                                    mContext, app);
1319                            app.waitDialog = d;
1320                            app.waitedForDebugger = true;
1321                            d.show();
1322                        }
1323                    } else {
1324                        if (app.waitDialog != null) {
1325                            app.waitDialog.dismiss();
1326                            app.waitDialog = null;
1327                        }
1328                    }
1329                }
1330            } break;
1331            case SERVICE_TIMEOUT_MSG: {
1332                if (mDidDexOpt) {
1333                    mDidDexOpt = false;
1334                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1335                    nmsg.obj = msg.obj;
1336                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1337                    return;
1338                }
1339                mServices.serviceTimeout((ProcessRecord)msg.obj);
1340            } break;
1341            case UPDATE_TIME_ZONE: {
1342                synchronized (ActivityManagerService.this) {
1343                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1344                        ProcessRecord r = mLruProcesses.get(i);
1345                        if (r.thread != null) {
1346                            try {
1347                                r.thread.updateTimeZone();
1348                            } catch (RemoteException ex) {
1349                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1350                            }
1351                        }
1352                    }
1353                }
1354            } break;
1355            case CLEAR_DNS_CACHE_MSG: {
1356                synchronized (ActivityManagerService.this) {
1357                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1358                        ProcessRecord r = mLruProcesses.get(i);
1359                        if (r.thread != null) {
1360                            try {
1361                                r.thread.clearDnsCache();
1362                            } catch (RemoteException ex) {
1363                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1364                            }
1365                        }
1366                    }
1367                }
1368            } break;
1369            case UPDATE_HTTP_PROXY_MSG: {
1370                ProxyInfo proxy = (ProxyInfo)msg.obj;
1371                String host = "";
1372                String port = "";
1373                String exclList = "";
1374                Uri pacFileUrl = Uri.EMPTY;
1375                if (proxy != null) {
1376                    host = proxy.getHost();
1377                    port = Integer.toString(proxy.getPort());
1378                    exclList = proxy.getExclusionListAsString();
1379                    pacFileUrl = proxy.getPacFileUrl();
1380                }
1381                synchronized (ActivityManagerService.this) {
1382                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1383                        ProcessRecord r = mLruProcesses.get(i);
1384                        if (r.thread != null) {
1385                            try {
1386                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1387                            } catch (RemoteException ex) {
1388                                Slog.w(TAG, "Failed to update http proxy for: " +
1389                                        r.info.processName);
1390                            }
1391                        }
1392                    }
1393                }
1394            } break;
1395            case SHOW_UID_ERROR_MSG: {
1396                String title = "System UIDs Inconsistent";
1397                String text = "UIDs on the system are inconsistent, you need to wipe your"
1398                        + " data partition or your device will be unstable.";
1399                Log.e(TAG, title + ": " + text);
1400                if (mShowDialogs) {
1401                    // XXX This is a temporary dialog, no need to localize.
1402                    AlertDialog d = new BaseErrorDialog(mContext);
1403                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1404                    d.setCancelable(false);
1405                    d.setTitle(title);
1406                    d.setMessage(text);
1407                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1408                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1409                    mUidAlert = d;
1410                    d.show();
1411                }
1412            } break;
1413            case IM_FEELING_LUCKY_MSG: {
1414                if (mUidAlert != null) {
1415                    mUidAlert.dismiss();
1416                    mUidAlert = null;
1417                }
1418            } break;
1419            case PROC_START_TIMEOUT_MSG: {
1420                if (mDidDexOpt) {
1421                    mDidDexOpt = false;
1422                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1423                    nmsg.obj = msg.obj;
1424                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1425                    return;
1426                }
1427                ProcessRecord app = (ProcessRecord)msg.obj;
1428                synchronized (ActivityManagerService.this) {
1429                    processStartTimedOutLocked(app);
1430                }
1431            } break;
1432            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1433                synchronized (ActivityManagerService.this) {
1434                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1435                }
1436            } break;
1437            case KILL_APPLICATION_MSG: {
1438                synchronized (ActivityManagerService.this) {
1439                    int appid = msg.arg1;
1440                    boolean restart = (msg.arg2 == 1);
1441                    Bundle bundle = (Bundle)msg.obj;
1442                    String pkg = bundle.getString("pkg");
1443                    String reason = bundle.getString("reason");
1444                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1445                            false, UserHandle.USER_ALL, reason);
1446                }
1447            } break;
1448            case FINALIZE_PENDING_INTENT_MSG: {
1449                ((PendingIntentRecord)msg.obj).completeFinalize();
1450            } break;
1451            case POST_HEAVY_NOTIFICATION_MSG: {
1452                INotificationManager inm = NotificationManager.getService();
1453                if (inm == null) {
1454                    return;
1455                }
1456
1457                ActivityRecord root = (ActivityRecord)msg.obj;
1458                ProcessRecord process = root.app;
1459                if (process == null) {
1460                    return;
1461                }
1462
1463                try {
1464                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1465                    String text = mContext.getString(R.string.heavy_weight_notification,
1466                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1467                    Notification notification = new Notification();
1468                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1469                    notification.when = 0;
1470                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1471                    notification.tickerText = text;
1472                    notification.defaults = 0; // please be quiet
1473                    notification.sound = null;
1474                    notification.vibrate = null;
1475                    notification.setLatestEventInfo(context, text,
1476                            mContext.getText(R.string.heavy_weight_notification_detail),
1477                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1478                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1479                                    new UserHandle(root.userId)));
1480
1481                    try {
1482                        int[] outId = new int[1];
1483                        inm.enqueueNotificationWithTag("android", "android", null,
1484                                R.string.heavy_weight_notification,
1485                                notification, outId, root.userId);
1486                    } catch (RuntimeException e) {
1487                        Slog.w(ActivityManagerService.TAG,
1488                                "Error showing notification for heavy-weight app", e);
1489                    } catch (RemoteException e) {
1490                    }
1491                } catch (NameNotFoundException e) {
1492                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1493                }
1494            } break;
1495            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1496                INotificationManager inm = NotificationManager.getService();
1497                if (inm == null) {
1498                    return;
1499                }
1500                try {
1501                    inm.cancelNotificationWithTag("android", null,
1502                            R.string.heavy_weight_notification,  msg.arg1);
1503                } catch (RuntimeException e) {
1504                    Slog.w(ActivityManagerService.TAG,
1505                            "Error canceling notification for service", e);
1506                } catch (RemoteException e) {
1507                }
1508            } break;
1509            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1510                synchronized (ActivityManagerService.this) {
1511                    checkExcessivePowerUsageLocked(true);
1512                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1513                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1514                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1515                }
1516            } break;
1517            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1518                synchronized (ActivityManagerService.this) {
1519                    ActivityRecord ar = (ActivityRecord)msg.obj;
1520                    if (mCompatModeDialog != null) {
1521                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1522                                ar.info.applicationInfo.packageName)) {
1523                            return;
1524                        }
1525                        mCompatModeDialog.dismiss();
1526                        mCompatModeDialog = null;
1527                    }
1528                    if (ar != null && false) {
1529                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1530                                ar.packageName)) {
1531                            int mode = mCompatModePackages.computeCompatModeLocked(
1532                                    ar.info.applicationInfo);
1533                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1534                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1535                                mCompatModeDialog = new CompatModeDialog(
1536                                        ActivityManagerService.this, mContext,
1537                                        ar.info.applicationInfo);
1538                                mCompatModeDialog.show();
1539                            }
1540                        }
1541                    }
1542                }
1543                break;
1544            }
1545            case DISPATCH_PROCESSES_CHANGED: {
1546                dispatchProcessesChanged();
1547                break;
1548            }
1549            case DISPATCH_PROCESS_DIED: {
1550                final int pid = msg.arg1;
1551                final int uid = msg.arg2;
1552                dispatchProcessDied(pid, uid);
1553                break;
1554            }
1555            case REPORT_MEM_USAGE_MSG: {
1556                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1557                Thread thread = new Thread() {
1558                    @Override public void run() {
1559                        final SparseArray<ProcessMemInfo> infoMap
1560                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1561                        for (int i=0, N=memInfos.size(); i<N; i++) {
1562                            ProcessMemInfo mi = memInfos.get(i);
1563                            infoMap.put(mi.pid, mi);
1564                        }
1565                        updateCpuStatsNow();
1566                        synchronized (mProcessCpuThread) {
1567                            final int N = mProcessCpuTracker.countStats();
1568                            for (int i=0; i<N; i++) {
1569                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1570                                if (st.vsize > 0) {
1571                                    long pss = Debug.getPss(st.pid, null);
1572                                    if (pss > 0) {
1573                                        if (infoMap.indexOfKey(st.pid) < 0) {
1574                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1575                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1576                                            mi.pss = pss;
1577                                            memInfos.add(mi);
1578                                        }
1579                                    }
1580                                }
1581                            }
1582                        }
1583
1584                        long totalPss = 0;
1585                        for (int i=0, N=memInfos.size(); i<N; i++) {
1586                            ProcessMemInfo mi = memInfos.get(i);
1587                            if (mi.pss == 0) {
1588                                mi.pss = Debug.getPss(mi.pid, null);
1589                            }
1590                            totalPss += mi.pss;
1591                        }
1592                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1593                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1594                                if (lhs.oomAdj != rhs.oomAdj) {
1595                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1596                                }
1597                                if (lhs.pss != rhs.pss) {
1598                                    return lhs.pss < rhs.pss ? 1 : -1;
1599                                }
1600                                return 0;
1601                            }
1602                        });
1603
1604                        StringBuilder tag = new StringBuilder(128);
1605                        StringBuilder stack = new StringBuilder(128);
1606                        tag.append("Low on memory -- ");
1607                        appendMemBucket(tag, totalPss, "total", false);
1608                        appendMemBucket(stack, totalPss, "total", true);
1609
1610                        StringBuilder logBuilder = new StringBuilder(1024);
1611                        logBuilder.append("Low on memory:\n");
1612
1613                        boolean firstLine = true;
1614                        int lastOomAdj = Integer.MIN_VALUE;
1615                        for (int i=0, N=memInfos.size(); i<N; i++) {
1616                            ProcessMemInfo mi = memInfos.get(i);
1617
1618                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1619                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1620                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1621                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1622                                if (lastOomAdj != mi.oomAdj) {
1623                                    lastOomAdj = mi.oomAdj;
1624                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1625                                        tag.append(" / ");
1626                                    }
1627                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1628                                        if (firstLine) {
1629                                            stack.append(":");
1630                                            firstLine = false;
1631                                        }
1632                                        stack.append("\n\t at ");
1633                                    } else {
1634                                        stack.append("$");
1635                                    }
1636                                } else {
1637                                    tag.append(" ");
1638                                    stack.append("$");
1639                                }
1640                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1641                                    appendMemBucket(tag, mi.pss, mi.name, false);
1642                                }
1643                                appendMemBucket(stack, mi.pss, mi.name, true);
1644                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1645                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1646                                    stack.append("(");
1647                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1648                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1649                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1650                                            stack.append(":");
1651                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1652                                        }
1653                                    }
1654                                    stack.append(")");
1655                                }
1656                            }
1657
1658                            logBuilder.append("  ");
1659                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1660                            logBuilder.append(' ');
1661                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1662                            logBuilder.append(' ');
1663                            ProcessList.appendRamKb(logBuilder, mi.pss);
1664                            logBuilder.append(" kB: ");
1665                            logBuilder.append(mi.name);
1666                            logBuilder.append(" (");
1667                            logBuilder.append(mi.pid);
1668                            logBuilder.append(") ");
1669                            logBuilder.append(mi.adjType);
1670                            logBuilder.append('\n');
1671                            if (mi.adjReason != null) {
1672                                logBuilder.append("                      ");
1673                                logBuilder.append(mi.adjReason);
1674                                logBuilder.append('\n');
1675                            }
1676                        }
1677
1678                        logBuilder.append("           ");
1679                        ProcessList.appendRamKb(logBuilder, totalPss);
1680                        logBuilder.append(" kB: TOTAL\n");
1681
1682                        long[] infos = new long[Debug.MEMINFO_COUNT];
1683                        Debug.getMemInfo(infos);
1684                        logBuilder.append("  MemInfo: ");
1685                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1686                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1687                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1688                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1689                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1690                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1691                            logBuilder.append("  ZRAM: ");
1692                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1693                            logBuilder.append(" kB RAM, ");
1694                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1695                            logBuilder.append(" kB swap total, ");
1696                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1697                            logBuilder.append(" kB swap free\n");
1698                        }
1699                        Slog.i(TAG, logBuilder.toString());
1700
1701                        StringBuilder dropBuilder = new StringBuilder(1024);
1702                        /*
1703                        StringWriter oomSw = new StringWriter();
1704                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1705                        StringWriter catSw = new StringWriter();
1706                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1707                        String[] emptyArgs = new String[] { };
1708                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1709                        oomPw.flush();
1710                        String oomString = oomSw.toString();
1711                        */
1712                        dropBuilder.append(stack);
1713                        dropBuilder.append('\n');
1714                        dropBuilder.append('\n');
1715                        dropBuilder.append(logBuilder);
1716                        dropBuilder.append('\n');
1717                        /*
1718                        dropBuilder.append(oomString);
1719                        dropBuilder.append('\n');
1720                        */
1721                        StringWriter catSw = new StringWriter();
1722                        synchronized (ActivityManagerService.this) {
1723                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1724                            String[] emptyArgs = new String[] { };
1725                            catPw.println();
1726                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1727                            catPw.println();
1728                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1729                                    false, false, null);
1730                            catPw.println();
1731                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1732                            catPw.flush();
1733                        }
1734                        dropBuilder.append(catSw.toString());
1735                        addErrorToDropBox("lowmem", null, "system_server", null,
1736                                null, tag.toString(), dropBuilder.toString(), null, null);
1737                        //Slog.i(TAG, "Sent to dropbox:");
1738                        //Slog.i(TAG, dropBuilder.toString());
1739                        synchronized (ActivityManagerService.this) {
1740                            long now = SystemClock.uptimeMillis();
1741                            if (mLastMemUsageReportTime < now) {
1742                                mLastMemUsageReportTime = now;
1743                            }
1744                        }
1745                    }
1746                };
1747                thread.start();
1748                break;
1749            }
1750            case REPORT_USER_SWITCH_MSG: {
1751                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1752                break;
1753            }
1754            case CONTINUE_USER_SWITCH_MSG: {
1755                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1756                break;
1757            }
1758            case USER_SWITCH_TIMEOUT_MSG: {
1759                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1760                break;
1761            }
1762            case IMMERSIVE_MODE_LOCK_MSG: {
1763                final boolean nextState = (msg.arg1 != 0);
1764                if (mUpdateLock.isHeld() != nextState) {
1765                    if (DEBUG_IMMERSIVE) {
1766                        final ActivityRecord r = (ActivityRecord) msg.obj;
1767                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1768                    }
1769                    if (nextState) {
1770                        mUpdateLock.acquire();
1771                    } else {
1772                        mUpdateLock.release();
1773                    }
1774                }
1775                break;
1776            }
1777            case PERSIST_URI_GRANTS_MSG: {
1778                writeGrantedUriPermissions();
1779                break;
1780            }
1781            case REQUEST_ALL_PSS_MSG: {
1782                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1783                break;
1784            }
1785            case START_PROFILES_MSG: {
1786                synchronized (ActivityManagerService.this) {
1787                    startProfilesLocked();
1788                }
1789                break;
1790            }
1791            case UPDATE_TIME: {
1792                synchronized (ActivityManagerService.this) {
1793                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1794                        ProcessRecord r = mLruProcesses.get(i);
1795                        if (r.thread != null) {
1796                            try {
1797                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1798                            } catch (RemoteException ex) {
1799                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1800                            }
1801                        }
1802                    }
1803                }
1804                break;
1805            }
1806            case SYSTEM_USER_START_MSG: {
1807                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1808                        Integer.toString(msg.arg1), msg.arg1);
1809                mSystemServiceManager.startUser(msg.arg1);
1810                break;
1811            }
1812            case SYSTEM_USER_CURRENT_MSG: {
1813                mBatteryStatsService.noteEvent(
1814                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1815                        Integer.toString(msg.arg2), msg.arg2);
1816                mBatteryStatsService.noteEvent(
1817                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1818                        Integer.toString(msg.arg1), msg.arg1);
1819                mSystemServiceManager.switchUser(msg.arg1);
1820                break;
1821            }
1822            case ENTER_ANIMATION_COMPLETE_MSG: {
1823                synchronized (ActivityManagerService.this) {
1824                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1825                    if (r != null && r.app != null && r.app.thread != null) {
1826                        try {
1827                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1828                        } catch (RemoteException e) {
1829                        }
1830                    }
1831                }
1832                break;
1833            }
1834            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1835                enableScreenAfterBoot();
1836                break;
1837            }
1838            }
1839        }
1840    };
1841
1842    static final int COLLECT_PSS_BG_MSG = 1;
1843
1844    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1845        @Override
1846        public void handleMessage(Message msg) {
1847            switch (msg.what) {
1848            case COLLECT_PSS_BG_MSG: {
1849                long start = SystemClock.uptimeMillis();
1850                MemInfoReader memInfo = null;
1851                synchronized (ActivityManagerService.this) {
1852                    if (mFullPssPending) {
1853                        mFullPssPending = false;
1854                        memInfo = new MemInfoReader();
1855                    }
1856                }
1857                if (memInfo != null) {
1858                    updateCpuStatsNow();
1859                    long nativeTotalPss = 0;
1860                    synchronized (mProcessCpuThread) {
1861                        final int N = mProcessCpuTracker.countStats();
1862                        for (int j=0; j<N; j++) {
1863                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1864                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1865                                // This is definitely an application process; skip it.
1866                                continue;
1867                            }
1868                            synchronized (mPidsSelfLocked) {
1869                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1870                                    // This is one of our own processes; skip it.
1871                                    continue;
1872                                }
1873                            }
1874                            nativeTotalPss += Debug.getPss(st.pid, null);
1875                        }
1876                    }
1877                    memInfo.readMemInfo();
1878                    synchronized (this) {
1879                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1880                                + (SystemClock.uptimeMillis()-start) + "ms");
1881                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1882                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1883                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1884                                        +memInfo.getSlabSizeKb(),
1885                                nativeTotalPss);
1886                    }
1887                }
1888
1889                int i=0, num=0;
1890                long[] tmp = new long[1];
1891                do {
1892                    ProcessRecord proc;
1893                    int procState;
1894                    int pid;
1895                    synchronized (ActivityManagerService.this) {
1896                        if (i >= mPendingPssProcesses.size()) {
1897                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1898                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1899                            mPendingPssProcesses.clear();
1900                            return;
1901                        }
1902                        proc = mPendingPssProcesses.get(i);
1903                        procState = proc.pssProcState;
1904                        if (proc.thread != null && procState == proc.setProcState) {
1905                            pid = proc.pid;
1906                        } else {
1907                            proc = null;
1908                            pid = 0;
1909                        }
1910                        i++;
1911                    }
1912                    if (proc != null) {
1913                        long pss = Debug.getPss(pid, tmp);
1914                        synchronized (ActivityManagerService.this) {
1915                            if (proc.thread != null && proc.setProcState == procState
1916                                    && proc.pid == pid) {
1917                                num++;
1918                                proc.lastPssTime = SystemClock.uptimeMillis();
1919                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1920                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1921                                        + ": " + pss + " lastPss=" + proc.lastPss
1922                                        + " state=" + ProcessList.makeProcStateString(procState));
1923                                if (proc.initialIdlePss == 0) {
1924                                    proc.initialIdlePss = pss;
1925                                }
1926                                proc.lastPss = pss;
1927                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1928                                    proc.lastCachedPss = pss;
1929                                }
1930                            }
1931                        }
1932                    }
1933                } while (true);
1934            }
1935            }
1936        }
1937    };
1938
1939    /**
1940     * Monitor for package changes and update our internal state.
1941     */
1942    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1943        @Override
1944        public void onPackageRemoved(String packageName, int uid) {
1945            // Remove all tasks with activities in the specified package from the list of recent tasks
1946            synchronized (ActivityManagerService.this) {
1947                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1948                    TaskRecord tr = mRecentTasks.get(i);
1949                    ComponentName cn = tr.intent.getComponent();
1950                    if (cn != null && cn.getPackageName().equals(packageName)) {
1951                        // If the package name matches, remove the task and kill the process
1952                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1953                    }
1954                }
1955            }
1956        }
1957
1958        @Override
1959        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1960            onPackageModified(packageName);
1961            return true;
1962        }
1963
1964        @Override
1965        public void onPackageModified(String packageName) {
1966            final PackageManager pm = mContext.getPackageManager();
1967            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1968                    new ArrayList<Pair<Intent, Integer>>();
1969            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1970            // Copy the list of recent tasks so that we don't hold onto the lock on
1971            // ActivityManagerService for long periods while checking if components exist.
1972            synchronized (ActivityManagerService.this) {
1973                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1974                    TaskRecord tr = mRecentTasks.get(i);
1975                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1976                }
1977            }
1978            // Check the recent tasks and filter out all tasks with components that no longer exist.
1979            Intent tmpI = new Intent();
1980            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1981                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1982                ComponentName cn = p.first.getComponent();
1983                if (cn != null && cn.getPackageName().equals(packageName)) {
1984                    try {
1985                        // Add the task to the list to remove if the component no longer exists
1986                        tmpI.setComponent(cn);
1987                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1988                            tasksToRemove.add(p.second);
1989                        }
1990                    } catch (Exception e) {}
1991                }
1992            }
1993            // Prune all the tasks with removed components from the list of recent tasks
1994            synchronized (ActivityManagerService.this) {
1995                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1996                    // Remove the task but don't kill the process (since other components in that
1997                    // package may still be running and in the background)
1998                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1999                }
2000            }
2001        }
2002
2003        @Override
2004        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2005            // Force stop the specified packages
2006            if (packages != null) {
2007                for (String pkg : packages) {
2008                    synchronized (ActivityManagerService.this) {
2009                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2010                                "finished booting")) {
2011                            return true;
2012                        }
2013                    }
2014                }
2015            }
2016            return false;
2017        }
2018    };
2019
2020    public void setSystemProcess() {
2021        try {
2022            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2023            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2024            ServiceManager.addService("meminfo", new MemBinder(this));
2025            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2026            ServiceManager.addService("dbinfo", new DbBinder(this));
2027            if (MONITOR_CPU_USAGE) {
2028                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2029            }
2030            ServiceManager.addService("permission", new PermissionController(this));
2031
2032            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2033                    "android", STOCK_PM_FLAGS);
2034            mSystemThread.installSystemApplicationInfo(info);
2035
2036            synchronized (this) {
2037                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2038                app.persistent = true;
2039                app.pid = MY_PID;
2040                app.maxAdj = ProcessList.SYSTEM_ADJ;
2041                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2042                mProcessNames.put(app.processName, app.uid, app);
2043                synchronized (mPidsSelfLocked) {
2044                    mPidsSelfLocked.put(app.pid, app);
2045                }
2046                updateLruProcessLocked(app, false, null);
2047                updateOomAdjLocked();
2048            }
2049        } catch (PackageManager.NameNotFoundException e) {
2050            throw new RuntimeException(
2051                    "Unable to find android system package", e);
2052        }
2053    }
2054
2055    public void setWindowManager(WindowManagerService wm) {
2056        mWindowManager = wm;
2057        mStackSupervisor.setWindowManager(wm);
2058    }
2059
2060    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2061        mUsageStatsService = usageStatsManager;
2062    }
2063
2064    public void startObservingNativeCrashes() {
2065        final NativeCrashListener ncl = new NativeCrashListener(this);
2066        ncl.start();
2067    }
2068
2069    public IAppOpsService getAppOpsService() {
2070        return mAppOpsService;
2071    }
2072
2073    static class MemBinder extends Binder {
2074        ActivityManagerService mActivityManagerService;
2075        MemBinder(ActivityManagerService activityManagerService) {
2076            mActivityManagerService = activityManagerService;
2077        }
2078
2079        @Override
2080        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2081            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2082                    != PackageManager.PERMISSION_GRANTED) {
2083                pw.println("Permission Denial: can't dump meminfo from from pid="
2084                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2085                        + " without permission " + android.Manifest.permission.DUMP);
2086                return;
2087            }
2088
2089            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2090        }
2091    }
2092
2093    static class GraphicsBinder extends Binder {
2094        ActivityManagerService mActivityManagerService;
2095        GraphicsBinder(ActivityManagerService activityManagerService) {
2096            mActivityManagerService = activityManagerService;
2097        }
2098
2099        @Override
2100        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2101            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2102                    != PackageManager.PERMISSION_GRANTED) {
2103                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2104                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2105                        + " without permission " + android.Manifest.permission.DUMP);
2106                return;
2107            }
2108
2109            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2110        }
2111    }
2112
2113    static class DbBinder extends Binder {
2114        ActivityManagerService mActivityManagerService;
2115        DbBinder(ActivityManagerService activityManagerService) {
2116            mActivityManagerService = activityManagerService;
2117        }
2118
2119        @Override
2120        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2121            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2122                    != PackageManager.PERMISSION_GRANTED) {
2123                pw.println("Permission Denial: can't dump dbinfo from from pid="
2124                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2125                        + " without permission " + android.Manifest.permission.DUMP);
2126                return;
2127            }
2128
2129            mActivityManagerService.dumpDbInfo(fd, pw, args);
2130        }
2131    }
2132
2133    static class CpuBinder extends Binder {
2134        ActivityManagerService mActivityManagerService;
2135        CpuBinder(ActivityManagerService activityManagerService) {
2136            mActivityManagerService = activityManagerService;
2137        }
2138
2139        @Override
2140        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2141            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2142                    != PackageManager.PERMISSION_GRANTED) {
2143                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2144                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2145                        + " without permission " + android.Manifest.permission.DUMP);
2146                return;
2147            }
2148
2149            synchronized (mActivityManagerService.mProcessCpuThread) {
2150                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2151                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2152                        SystemClock.uptimeMillis()));
2153            }
2154        }
2155    }
2156
2157    public static final class Lifecycle extends SystemService {
2158        private final ActivityManagerService mService;
2159
2160        public Lifecycle(Context context) {
2161            super(context);
2162            mService = new ActivityManagerService(context);
2163        }
2164
2165        @Override
2166        public void onStart() {
2167            mService.start();
2168        }
2169
2170        public ActivityManagerService getService() {
2171            return mService;
2172        }
2173    }
2174
2175    // Note: This method is invoked on the main thread but may need to attach various
2176    // handlers to other threads.  So take care to be explicit about the looper.
2177    public ActivityManagerService(Context systemContext) {
2178        mContext = systemContext;
2179        mFactoryTest = FactoryTest.getMode();
2180        mSystemThread = ActivityThread.currentActivityThread();
2181
2182        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2183
2184        mHandlerThread = new ServiceThread(TAG,
2185                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2186        mHandlerThread.start();
2187        mHandler = new MainHandler(mHandlerThread.getLooper());
2188
2189        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2190                "foreground", BROADCAST_FG_TIMEOUT, false);
2191        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2192                "background", BROADCAST_BG_TIMEOUT, true);
2193        mBroadcastQueues[0] = mFgBroadcastQueue;
2194        mBroadcastQueues[1] = mBgBroadcastQueue;
2195
2196        mServices = new ActiveServices(this);
2197        mProviderMap = new ProviderMap(this);
2198
2199        // TODO: Move creation of battery stats service outside of activity manager service.
2200        File dataDir = Environment.getDataDirectory();
2201        File systemDir = new File(dataDir, "system");
2202        systemDir.mkdirs();
2203        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2204        mBatteryStatsService.getActiveStatistics().readLocked();
2205        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2206        mOnBattery = DEBUG_POWER ? true
2207                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2208        mBatteryStatsService.getActiveStatistics().setCallback(this);
2209
2210        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2211
2212        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2213
2214        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2215
2216        // User 0 is the first and only user that runs at boot.
2217        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2218        mUserLru.add(Integer.valueOf(0));
2219        updateStartedUserArrayLocked();
2220
2221        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2222            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2223
2224        mConfiguration.setToDefaults();
2225        mConfiguration.setLocale(Locale.getDefault());
2226
2227        mConfigurationSeq = mConfiguration.seq = 1;
2228        mProcessCpuTracker.init();
2229
2230        mHasRecents = mContext.getResources().getBoolean(
2231                com.android.internal.R.bool.config_hasRecents);
2232
2233        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2234        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2235        mStackSupervisor = new ActivityStackSupervisor(this);
2236        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2237
2238        mProcessCpuThread = new Thread("CpuTracker") {
2239            @Override
2240            public void run() {
2241                while (true) {
2242                    try {
2243                        try {
2244                            synchronized(this) {
2245                                final long now = SystemClock.uptimeMillis();
2246                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2247                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2248                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2249                                //        + ", write delay=" + nextWriteDelay);
2250                                if (nextWriteDelay < nextCpuDelay) {
2251                                    nextCpuDelay = nextWriteDelay;
2252                                }
2253                                if (nextCpuDelay > 0) {
2254                                    mProcessCpuMutexFree.set(true);
2255                                    this.wait(nextCpuDelay);
2256                                }
2257                            }
2258                        } catch (InterruptedException e) {
2259                        }
2260                        updateCpuStatsNow();
2261                    } catch (Exception e) {
2262                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2263                    }
2264                }
2265            }
2266        };
2267
2268        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2269
2270        Watchdog.getInstance().addMonitor(this);
2271        Watchdog.getInstance().addThread(mHandler);
2272    }
2273
2274    public void setSystemServiceManager(SystemServiceManager mgr) {
2275        mSystemServiceManager = mgr;
2276    }
2277
2278    private void start() {
2279        Process.removeAllProcessGroups();
2280        mProcessCpuThread.start();
2281
2282        mBatteryStatsService.publish(mContext);
2283        mAppOpsService.publish(mContext);
2284        Slog.d("AppOps", "AppOpsService published");
2285        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2286    }
2287
2288    public void initPowerManagement() {
2289        mStackSupervisor.initPowerManagement();
2290        mBatteryStatsService.initPowerManagement();
2291    }
2292
2293    @Override
2294    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2295            throws RemoteException {
2296        if (code == SYSPROPS_TRANSACTION) {
2297            // We need to tell all apps about the system property change.
2298            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2299            synchronized(this) {
2300                final int NP = mProcessNames.getMap().size();
2301                for (int ip=0; ip<NP; ip++) {
2302                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2303                    final int NA = apps.size();
2304                    for (int ia=0; ia<NA; ia++) {
2305                        ProcessRecord app = apps.valueAt(ia);
2306                        if (app.thread != null) {
2307                            procs.add(app.thread.asBinder());
2308                        }
2309                    }
2310                }
2311            }
2312
2313            int N = procs.size();
2314            for (int i=0; i<N; i++) {
2315                Parcel data2 = Parcel.obtain();
2316                try {
2317                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2318                } catch (RemoteException e) {
2319                }
2320                data2.recycle();
2321            }
2322        }
2323        try {
2324            return super.onTransact(code, data, reply, flags);
2325        } catch (RuntimeException e) {
2326            // The activity manager only throws security exceptions, so let's
2327            // log all others.
2328            if (!(e instanceof SecurityException)) {
2329                Slog.wtf(TAG, "Activity Manager Crash", e);
2330            }
2331            throw e;
2332        }
2333    }
2334
2335    void updateCpuStats() {
2336        final long now = SystemClock.uptimeMillis();
2337        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2338            return;
2339        }
2340        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2341            synchronized (mProcessCpuThread) {
2342                mProcessCpuThread.notify();
2343            }
2344        }
2345    }
2346
2347    void updateCpuStatsNow() {
2348        synchronized (mProcessCpuThread) {
2349            mProcessCpuMutexFree.set(false);
2350            final long now = SystemClock.uptimeMillis();
2351            boolean haveNewCpuStats = false;
2352
2353            if (MONITOR_CPU_USAGE &&
2354                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2355                mLastCpuTime.set(now);
2356                haveNewCpuStats = true;
2357                mProcessCpuTracker.update();
2358                //Slog.i(TAG, mProcessCpu.printCurrentState());
2359                //Slog.i(TAG, "Total CPU usage: "
2360                //        + mProcessCpu.getTotalCpuPercent() + "%");
2361
2362                // Slog the cpu usage if the property is set.
2363                if ("true".equals(SystemProperties.get("events.cpu"))) {
2364                    int user = mProcessCpuTracker.getLastUserTime();
2365                    int system = mProcessCpuTracker.getLastSystemTime();
2366                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2367                    int irq = mProcessCpuTracker.getLastIrqTime();
2368                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2369                    int idle = mProcessCpuTracker.getLastIdleTime();
2370
2371                    int total = user + system + iowait + irq + softIrq + idle;
2372                    if (total == 0) total = 1;
2373
2374                    EventLog.writeEvent(EventLogTags.CPU,
2375                            ((user+system+iowait+irq+softIrq) * 100) / total,
2376                            (user * 100) / total,
2377                            (system * 100) / total,
2378                            (iowait * 100) / total,
2379                            (irq * 100) / total,
2380                            (softIrq * 100) / total);
2381                }
2382            }
2383
2384            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2385            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2386            synchronized(bstats) {
2387                synchronized(mPidsSelfLocked) {
2388                    if (haveNewCpuStats) {
2389                        if (mOnBattery) {
2390                            int perc = bstats.startAddingCpuLocked();
2391                            int totalUTime = 0;
2392                            int totalSTime = 0;
2393                            final int N = mProcessCpuTracker.countStats();
2394                            for (int i=0; i<N; i++) {
2395                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2396                                if (!st.working) {
2397                                    continue;
2398                                }
2399                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2400                                int otherUTime = (st.rel_utime*perc)/100;
2401                                int otherSTime = (st.rel_stime*perc)/100;
2402                                totalUTime += otherUTime;
2403                                totalSTime += otherSTime;
2404                                if (pr != null) {
2405                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2406                                    if (ps == null || !ps.isActive()) {
2407                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2408                                                pr.info.uid, pr.processName);
2409                                    }
2410                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2411                                            st.rel_stime-otherSTime);
2412                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2413                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2414                                } else {
2415                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2416                                    if (ps == null || !ps.isActive()) {
2417                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2418                                                bstats.mapUid(st.uid), st.name);
2419                                    }
2420                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2421                                            st.rel_stime-otherSTime);
2422                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2423                                }
2424                            }
2425                            bstats.finishAddingCpuLocked(perc, totalUTime,
2426                                    totalSTime, cpuSpeedTimes);
2427                        }
2428                    }
2429                }
2430
2431                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2432                    mLastWriteTime = now;
2433                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2434                }
2435            }
2436        }
2437    }
2438
2439    @Override
2440    public void batteryNeedsCpuUpdate() {
2441        updateCpuStatsNow();
2442    }
2443
2444    @Override
2445    public void batteryPowerChanged(boolean onBattery) {
2446        // When plugging in, update the CPU stats first before changing
2447        // the plug state.
2448        updateCpuStatsNow();
2449        synchronized (this) {
2450            synchronized(mPidsSelfLocked) {
2451                mOnBattery = DEBUG_POWER ? true : onBattery;
2452            }
2453        }
2454    }
2455
2456    /**
2457     * Initialize the application bind args. These are passed to each
2458     * process when the bindApplication() IPC is sent to the process. They're
2459     * lazily setup to make sure the services are running when they're asked for.
2460     */
2461    private HashMap<String, IBinder> getCommonServicesLocked() {
2462        if (mAppBindArgs == null) {
2463            mAppBindArgs = new HashMap<String, IBinder>();
2464
2465            // Setup the application init args
2466            mAppBindArgs.put("package", ServiceManager.getService("package"));
2467            mAppBindArgs.put("window", ServiceManager.getService("window"));
2468            mAppBindArgs.put(Context.ALARM_SERVICE,
2469                    ServiceManager.getService(Context.ALARM_SERVICE));
2470        }
2471        return mAppBindArgs;
2472    }
2473
2474    final void setFocusedActivityLocked(ActivityRecord r) {
2475        if (mFocusedActivity != r) {
2476            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2477            mFocusedActivity = r;
2478            if (r.task != null && r.task.voiceInteractor != null) {
2479                startRunningVoiceLocked();
2480            } else {
2481                finishRunningVoiceLocked();
2482            }
2483            mStackSupervisor.setFocusedStack(r);
2484            if (r != null) {
2485                mWindowManager.setFocusedApp(r.appToken, true);
2486            }
2487            applyUpdateLockStateLocked(r);
2488        }
2489    }
2490
2491    final void clearFocusedActivity(ActivityRecord r) {
2492        if (mFocusedActivity == r) {
2493            mFocusedActivity = null;
2494        }
2495    }
2496
2497    @Override
2498    public void setFocusedStack(int stackId) {
2499        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2500        synchronized (ActivityManagerService.this) {
2501            ActivityStack stack = mStackSupervisor.getStack(stackId);
2502            if (stack != null) {
2503                ActivityRecord r = stack.topRunningActivityLocked(null);
2504                if (r != null) {
2505                    setFocusedActivityLocked(r);
2506                }
2507            }
2508        }
2509    }
2510
2511    @Override
2512    public void notifyActivityDrawn(IBinder token) {
2513        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2514        synchronized (this) {
2515            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2516            if (r != null) {
2517                r.task.stack.notifyActivityDrawnLocked(r);
2518            }
2519        }
2520    }
2521
2522    final void applyUpdateLockStateLocked(ActivityRecord r) {
2523        // Modifications to the UpdateLock state are done on our handler, outside
2524        // the activity manager's locks.  The new state is determined based on the
2525        // state *now* of the relevant activity record.  The object is passed to
2526        // the handler solely for logging detail, not to be consulted/modified.
2527        final boolean nextState = r != null && r.immersive;
2528        mHandler.sendMessage(
2529                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2530    }
2531
2532    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2533        Message msg = Message.obtain();
2534        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2535        msg.obj = r.task.askedCompatMode ? null : r;
2536        mHandler.sendMessage(msg);
2537    }
2538
2539    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2540            String what, Object obj, ProcessRecord srcApp) {
2541        app.lastActivityTime = now;
2542
2543        if (app.activities.size() > 0) {
2544            // Don't want to touch dependent processes that are hosting activities.
2545            return index;
2546        }
2547
2548        int lrui = mLruProcesses.lastIndexOf(app);
2549        if (lrui < 0) {
2550            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2551                    + what + " " + obj + " from " + srcApp);
2552            return index;
2553        }
2554
2555        if (lrui >= index) {
2556            // Don't want to cause this to move dependent processes *back* in the
2557            // list as if they were less frequently used.
2558            return index;
2559        }
2560
2561        if (lrui >= mLruProcessActivityStart) {
2562            // Don't want to touch dependent processes that are hosting activities.
2563            return index;
2564        }
2565
2566        mLruProcesses.remove(lrui);
2567        if (index > 0) {
2568            index--;
2569        }
2570        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2571                + " in LRU list: " + app);
2572        mLruProcesses.add(index, app);
2573        return index;
2574    }
2575
2576    final void removeLruProcessLocked(ProcessRecord app) {
2577        int lrui = mLruProcesses.lastIndexOf(app);
2578        if (lrui >= 0) {
2579            if (lrui <= mLruProcessActivityStart) {
2580                mLruProcessActivityStart--;
2581            }
2582            if (lrui <= mLruProcessServiceStart) {
2583                mLruProcessServiceStart--;
2584            }
2585            mLruProcesses.remove(lrui);
2586        }
2587    }
2588
2589    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2590            ProcessRecord client) {
2591        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2592                || app.treatLikeActivity;
2593        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2594        if (!activityChange && hasActivity) {
2595            // The process has activities, so we are only allowing activity-based adjustments
2596            // to move it.  It should be kept in the front of the list with other
2597            // processes that have activities, and we don't want those to change their
2598            // order except due to activity operations.
2599            return;
2600        }
2601
2602        mLruSeq++;
2603        final long now = SystemClock.uptimeMillis();
2604        app.lastActivityTime = now;
2605
2606        // First a quick reject: if the app is already at the position we will
2607        // put it, then there is nothing to do.
2608        if (hasActivity) {
2609            final int N = mLruProcesses.size();
2610            if (N > 0 && mLruProcesses.get(N-1) == app) {
2611                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2612                return;
2613            }
2614        } else {
2615            if (mLruProcessServiceStart > 0
2616                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2617                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2618                return;
2619            }
2620        }
2621
2622        int lrui = mLruProcesses.lastIndexOf(app);
2623
2624        if (app.persistent && lrui >= 0) {
2625            // We don't care about the position of persistent processes, as long as
2626            // they are in the list.
2627            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2628            return;
2629        }
2630
2631        /* In progress: compute new position first, so we can avoid doing work
2632           if the process is not actually going to move.  Not yet working.
2633        int addIndex;
2634        int nextIndex;
2635        boolean inActivity = false, inService = false;
2636        if (hasActivity) {
2637            // Process has activities, put it at the very tipsy-top.
2638            addIndex = mLruProcesses.size();
2639            nextIndex = mLruProcessServiceStart;
2640            inActivity = true;
2641        } else if (hasService) {
2642            // Process has services, put it at the top of the service list.
2643            addIndex = mLruProcessActivityStart;
2644            nextIndex = mLruProcessServiceStart;
2645            inActivity = true;
2646            inService = true;
2647        } else  {
2648            // Process not otherwise of interest, it goes to the top of the non-service area.
2649            addIndex = mLruProcessServiceStart;
2650            if (client != null) {
2651                int clientIndex = mLruProcesses.lastIndexOf(client);
2652                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2653                        + app);
2654                if (clientIndex >= 0 && addIndex > clientIndex) {
2655                    addIndex = clientIndex;
2656                }
2657            }
2658            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2659        }
2660
2661        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2662                + mLruProcessActivityStart + "): " + app);
2663        */
2664
2665        if (lrui >= 0) {
2666            if (lrui < mLruProcessActivityStart) {
2667                mLruProcessActivityStart--;
2668            }
2669            if (lrui < mLruProcessServiceStart) {
2670                mLruProcessServiceStart--;
2671            }
2672            /*
2673            if (addIndex > lrui) {
2674                addIndex--;
2675            }
2676            if (nextIndex > lrui) {
2677                nextIndex--;
2678            }
2679            */
2680            mLruProcesses.remove(lrui);
2681        }
2682
2683        /*
2684        mLruProcesses.add(addIndex, app);
2685        if (inActivity) {
2686            mLruProcessActivityStart++;
2687        }
2688        if (inService) {
2689            mLruProcessActivityStart++;
2690        }
2691        */
2692
2693        int nextIndex;
2694        if (hasActivity) {
2695            final int N = mLruProcesses.size();
2696            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2697                // Process doesn't have activities, but has clients with
2698                // activities...  move it up, but one below the top (the top
2699                // should always have a real activity).
2700                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2701                mLruProcesses.add(N-1, app);
2702                // To keep it from spamming the LRU list (by making a bunch of clients),
2703                // we will push down any other entries owned by the app.
2704                final int uid = app.info.uid;
2705                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2706                    ProcessRecord subProc = mLruProcesses.get(i);
2707                    if (subProc.info.uid == uid) {
2708                        // We want to push this one down the list.  If the process after
2709                        // it is for the same uid, however, don't do so, because we don't
2710                        // want them internally to be re-ordered.
2711                        if (mLruProcesses.get(i-1).info.uid != uid) {
2712                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2713                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2714                            ProcessRecord tmp = mLruProcesses.get(i);
2715                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2716                            mLruProcesses.set(i-1, tmp);
2717                            i--;
2718                        }
2719                    } else {
2720                        // A gap, we can stop here.
2721                        break;
2722                    }
2723                }
2724            } else {
2725                // Process has activities, put it at the very tipsy-top.
2726                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2727                mLruProcesses.add(app);
2728            }
2729            nextIndex = mLruProcessServiceStart;
2730        } else if (hasService) {
2731            // Process has services, put it at the top of the service list.
2732            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2733            mLruProcesses.add(mLruProcessActivityStart, app);
2734            nextIndex = mLruProcessServiceStart;
2735            mLruProcessActivityStart++;
2736        } else  {
2737            // Process not otherwise of interest, it goes to the top of the non-service area.
2738            int index = mLruProcessServiceStart;
2739            if (client != null) {
2740                // If there is a client, don't allow the process to be moved up higher
2741                // in the list than that client.
2742                int clientIndex = mLruProcesses.lastIndexOf(client);
2743                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2744                        + " when updating " + app);
2745                if (clientIndex <= lrui) {
2746                    // Don't allow the client index restriction to push it down farther in the
2747                    // list than it already is.
2748                    clientIndex = lrui;
2749                }
2750                if (clientIndex >= 0 && index > clientIndex) {
2751                    index = clientIndex;
2752                }
2753            }
2754            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2755            mLruProcesses.add(index, app);
2756            nextIndex = index-1;
2757            mLruProcessActivityStart++;
2758            mLruProcessServiceStart++;
2759        }
2760
2761        // If the app is currently using a content provider or service,
2762        // bump those processes as well.
2763        for (int j=app.connections.size()-1; j>=0; j--) {
2764            ConnectionRecord cr = app.connections.valueAt(j);
2765            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2766                    && cr.binding.service.app != null
2767                    && cr.binding.service.app.lruSeq != mLruSeq
2768                    && !cr.binding.service.app.persistent) {
2769                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2770                        "service connection", cr, app);
2771            }
2772        }
2773        for (int j=app.conProviders.size()-1; j>=0; j--) {
2774            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2775            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2776                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2777                        "provider reference", cpr, app);
2778            }
2779        }
2780    }
2781
2782    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2783        if (uid == Process.SYSTEM_UID) {
2784            // The system gets to run in any process.  If there are multiple
2785            // processes with the same uid, just pick the first (this
2786            // should never happen).
2787            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2788            if (procs == null) return null;
2789            final int N = procs.size();
2790            for (int i = 0; i < N; i++) {
2791                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2792            }
2793        }
2794        ProcessRecord proc = mProcessNames.get(processName, uid);
2795        if (false && proc != null && !keepIfLarge
2796                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2797                && proc.lastCachedPss >= 4000) {
2798            // Turn this condition on to cause killing to happen regularly, for testing.
2799            if (proc.baseProcessTracker != null) {
2800                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2801            }
2802            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2803                    + "k from cached");
2804        } else if (proc != null && !keepIfLarge
2805                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2806                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2807            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2808            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2809                if (proc.baseProcessTracker != null) {
2810                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2811                }
2812                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2813                        + "k from cached");
2814            }
2815        }
2816        return proc;
2817    }
2818
2819    void ensurePackageDexOpt(String packageName) {
2820        IPackageManager pm = AppGlobals.getPackageManager();
2821        try {
2822            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2823                mDidDexOpt = true;
2824            }
2825        } catch (RemoteException e) {
2826        }
2827    }
2828
2829    boolean isNextTransitionForward() {
2830        int transit = mWindowManager.getPendingAppTransition();
2831        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2832                || transit == AppTransition.TRANSIT_TASK_OPEN
2833                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2834    }
2835
2836    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2837            String processName, String abiOverride, int uid, Runnable crashHandler) {
2838        synchronized(this) {
2839            ApplicationInfo info = new ApplicationInfo();
2840            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2841            // For isolated processes, the former contains the parent's uid and the latter the
2842            // actual uid of the isolated process.
2843            // In the special case introduced by this method (which is, starting an isolated
2844            // process directly from the SystemServer without an actual parent app process) the
2845            // closest thing to a parent's uid is SYSTEM_UID.
2846            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2847            // the |isolated| logic in the ProcessRecord constructor.
2848            info.uid = Process.SYSTEM_UID;
2849            info.processName = processName;
2850            info.className = entryPoint;
2851            info.packageName = "android";
2852            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2853                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2854                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2855                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2856                    crashHandler);
2857            return proc != null ? proc.pid : 0;
2858        }
2859    }
2860
2861    final ProcessRecord startProcessLocked(String processName,
2862            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2863            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2864            boolean isolated, boolean keepIfLarge) {
2865        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2866                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2867                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2868                null /* crashHandler */);
2869    }
2870
2871    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2872            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2873            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2874            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2875        ProcessRecord app;
2876        if (!isolated) {
2877            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2878        } else {
2879            // If this is an isolated process, it can't re-use an existing process.
2880            app = null;
2881        }
2882        // We don't have to do anything more if:
2883        // (1) There is an existing application record; and
2884        // (2) The caller doesn't think it is dead, OR there is no thread
2885        //     object attached to it so we know it couldn't have crashed; and
2886        // (3) There is a pid assigned to it, so it is either starting or
2887        //     already running.
2888        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2889                + " app=" + app + " knownToBeDead=" + knownToBeDead
2890                + " thread=" + (app != null ? app.thread : null)
2891                + " pid=" + (app != null ? app.pid : -1));
2892        if (app != null && app.pid > 0) {
2893            if (!knownToBeDead || app.thread == null) {
2894                // We already have the app running, or are waiting for it to
2895                // come up (we have a pid but not yet its thread), so keep it.
2896                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2897                // If this is a new package in the process, add the package to the list
2898                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2899                return app;
2900            }
2901
2902            // An application record is attached to a previous process,
2903            // clean it up now.
2904            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2905            Process.killProcessGroup(app.info.uid, app.pid);
2906            handleAppDiedLocked(app, true, true);
2907        }
2908
2909        String hostingNameStr = hostingName != null
2910                ? hostingName.flattenToShortString() : null;
2911
2912        if (!isolated) {
2913            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2914                // If we are in the background, then check to see if this process
2915                // is bad.  If so, we will just silently fail.
2916                if (mBadProcesses.get(info.processName, info.uid) != null) {
2917                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2918                            + "/" + info.processName);
2919                    return null;
2920                }
2921            } else {
2922                // When the user is explicitly starting a process, then clear its
2923                // crash count so that we won't make it bad until they see at
2924                // least one crash dialog again, and make the process good again
2925                // if it had been bad.
2926                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2927                        + "/" + info.processName);
2928                mProcessCrashTimes.remove(info.processName, info.uid);
2929                if (mBadProcesses.get(info.processName, info.uid) != null) {
2930                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2931                            UserHandle.getUserId(info.uid), info.uid,
2932                            info.processName);
2933                    mBadProcesses.remove(info.processName, info.uid);
2934                    if (app != null) {
2935                        app.bad = false;
2936                    }
2937                }
2938            }
2939        }
2940
2941        if (app == null) {
2942            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2943            app.crashHandler = crashHandler;
2944            if (app == null) {
2945                Slog.w(TAG, "Failed making new process record for "
2946                        + processName + "/" + info.uid + " isolated=" + isolated);
2947                return null;
2948            }
2949            mProcessNames.put(processName, app.uid, app);
2950            if (isolated) {
2951                mIsolatedProcesses.put(app.uid, app);
2952            }
2953        } else {
2954            // If this is a new package in the process, add the package to the list
2955            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2956        }
2957
2958        // If the system is not ready yet, then hold off on starting this
2959        // process until it is.
2960        if (!mProcessesReady
2961                && !isAllowedWhileBooting(info)
2962                && !allowWhileBooting) {
2963            if (!mProcessesOnHold.contains(app)) {
2964                mProcessesOnHold.add(app);
2965            }
2966            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2967            return app;
2968        }
2969
2970        startProcessLocked(
2971                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2972        return (app.pid != 0) ? app : null;
2973    }
2974
2975    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2976        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2977    }
2978
2979    private final void startProcessLocked(ProcessRecord app,
2980            String hostingType, String hostingNameStr) {
2981        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2982                null /* entryPoint */, null /* entryPointArgs */);
2983    }
2984
2985    private final void startProcessLocked(ProcessRecord app, String hostingType,
2986            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2987        if (app.pid > 0 && app.pid != MY_PID) {
2988            synchronized (mPidsSelfLocked) {
2989                mPidsSelfLocked.remove(app.pid);
2990                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2991            }
2992            app.setPid(0);
2993        }
2994
2995        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2996                "startProcessLocked removing on hold: " + app);
2997        mProcessesOnHold.remove(app);
2998
2999        updateCpuStats();
3000
3001        try {
3002            int uid = app.uid;
3003
3004            int[] gids = null;
3005            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3006            if (!app.isolated) {
3007                int[] permGids = null;
3008                try {
3009                    final PackageManager pm = mContext.getPackageManager();
3010                    permGids = pm.getPackageGids(app.info.packageName);
3011
3012                    if (Environment.isExternalStorageEmulated()) {
3013                        if (pm.checkPermission(
3014                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3015                                app.info.packageName) == PERMISSION_GRANTED) {
3016                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3017                        } else {
3018                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3019                        }
3020                    }
3021                } catch (PackageManager.NameNotFoundException e) {
3022                    Slog.w(TAG, "Unable to retrieve gids", e);
3023                }
3024
3025                /*
3026                 * Add shared application and profile GIDs so applications can share some
3027                 * resources like shared libraries and access user-wide resources
3028                 */
3029                if (permGids == null) {
3030                    gids = new int[2];
3031                } else {
3032                    gids = new int[permGids.length + 2];
3033                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3034                }
3035                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3036                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3037            }
3038            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3039                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3040                        && mTopComponent != null
3041                        && app.processName.equals(mTopComponent.getPackageName())) {
3042                    uid = 0;
3043                }
3044                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3045                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3046                    uid = 0;
3047                }
3048            }
3049            int debugFlags = 0;
3050            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3051                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3052                // Also turn on CheckJNI for debuggable apps. It's quite
3053                // awkward to turn on otherwise.
3054                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3055            }
3056            // Run the app in safe mode if its manifest requests so or the
3057            // system is booted in safe mode.
3058            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3059                mSafeMode == true) {
3060                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3061            }
3062            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3063                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3064            }
3065            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3066                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3067            }
3068            if ("1".equals(SystemProperties.get("debug.assert"))) {
3069                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3070            }
3071
3072            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3073            if (requiredAbi == null) {
3074                requiredAbi = Build.SUPPORTED_ABIS[0];
3075            }
3076
3077            // Start the process.  It will either succeed and return a result containing
3078            // the PID of the new process, or else throw a RuntimeException.
3079            boolean isActivityProcess = (entryPoint == null);
3080            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3081            Process.ProcessStartResult startResult = Process.start(entryPoint,
3082                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3083                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3084
3085            if (app.isolated) {
3086                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3087            }
3088            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3089
3090            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3091                    UserHandle.getUserId(uid), startResult.pid, uid,
3092                    app.processName, hostingType,
3093                    hostingNameStr != null ? hostingNameStr : "");
3094
3095            if (app.persistent) {
3096                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3097            }
3098
3099            StringBuilder buf = mStringBuilder;
3100            buf.setLength(0);
3101            buf.append("Start proc ");
3102            buf.append(app.processName);
3103            if (!isActivityProcess) {
3104                buf.append(" [");
3105                buf.append(entryPoint);
3106                buf.append("]");
3107            }
3108            buf.append(" for ");
3109            buf.append(hostingType);
3110            if (hostingNameStr != null) {
3111                buf.append(" ");
3112                buf.append(hostingNameStr);
3113            }
3114            buf.append(": pid=");
3115            buf.append(startResult.pid);
3116            buf.append(" uid=");
3117            buf.append(uid);
3118            buf.append(" gids={");
3119            if (gids != null) {
3120                for (int gi=0; gi<gids.length; gi++) {
3121                    if (gi != 0) buf.append(", ");
3122                    buf.append(gids[gi]);
3123
3124                }
3125            }
3126            buf.append("}");
3127            if (requiredAbi != null) {
3128                buf.append(" abi=");
3129                buf.append(requiredAbi);
3130            }
3131            Slog.i(TAG, buf.toString());
3132            app.setPid(startResult.pid);
3133            app.usingWrapper = startResult.usingWrapper;
3134            app.removed = false;
3135            app.killedByAm = false;
3136            synchronized (mPidsSelfLocked) {
3137                this.mPidsSelfLocked.put(startResult.pid, app);
3138                if (isActivityProcess) {
3139                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3140                    msg.obj = app;
3141                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3142                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3143                }
3144            }
3145        } catch (RuntimeException e) {
3146            // XXX do better error recovery.
3147            app.setPid(0);
3148            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3149            if (app.isolated) {
3150                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3151            }
3152            Slog.e(TAG, "Failure starting process " + app.processName, e);
3153        }
3154    }
3155
3156    void updateUsageStats(ActivityRecord component, boolean resumed) {
3157        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3158        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3159        if (resumed) {
3160            if (mUsageStatsService != null) {
3161                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3162                        System.currentTimeMillis(),
3163                        UsageStats.Event.MOVE_TO_FOREGROUND);
3164            }
3165            synchronized (stats) {
3166                stats.noteActivityResumedLocked(component.app.uid);
3167            }
3168        } else {
3169            if (mUsageStatsService != null) {
3170                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3171                        System.currentTimeMillis(),
3172                        UsageStats.Event.MOVE_TO_BACKGROUND);
3173            }
3174            synchronized (stats) {
3175                stats.noteActivityPausedLocked(component.app.uid);
3176            }
3177        }
3178    }
3179
3180    Intent getHomeIntent() {
3181        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3182        intent.setComponent(mTopComponent);
3183        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3184            intent.addCategory(Intent.CATEGORY_HOME);
3185        }
3186        return intent;
3187    }
3188
3189    boolean startHomeActivityLocked(int userId) {
3190        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3191                && mTopAction == null) {
3192            // We are running in factory test mode, but unable to find
3193            // the factory test app, so just sit around displaying the
3194            // error message and don't try to start anything.
3195            return false;
3196        }
3197        Intent intent = getHomeIntent();
3198        ActivityInfo aInfo =
3199            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3200        if (aInfo != null) {
3201            intent.setComponent(new ComponentName(
3202                    aInfo.applicationInfo.packageName, aInfo.name));
3203            // Don't do this if the home app is currently being
3204            // instrumented.
3205            aInfo = new ActivityInfo(aInfo);
3206            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3207            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3208                    aInfo.applicationInfo.uid, true);
3209            if (app == null || app.instrumentationClass == null) {
3210                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3211                mStackSupervisor.startHomeActivity(intent, aInfo);
3212            }
3213        }
3214
3215        return true;
3216    }
3217
3218    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3219        ActivityInfo ai = null;
3220        ComponentName comp = intent.getComponent();
3221        try {
3222            if (comp != null) {
3223                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3224            } else {
3225                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3226                        intent,
3227                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3228                            flags, userId);
3229
3230                if (info != null) {
3231                    ai = info.activityInfo;
3232                }
3233            }
3234        } catch (RemoteException e) {
3235            // ignore
3236        }
3237
3238        return ai;
3239    }
3240
3241    /**
3242     * Starts the "new version setup screen" if appropriate.
3243     */
3244    void startSetupActivityLocked() {
3245        // Only do this once per boot.
3246        if (mCheckedForSetup) {
3247            return;
3248        }
3249
3250        // We will show this screen if the current one is a different
3251        // version than the last one shown, and we are not running in
3252        // low-level factory test mode.
3253        final ContentResolver resolver = mContext.getContentResolver();
3254        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3255                Settings.Global.getInt(resolver,
3256                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3257            mCheckedForSetup = true;
3258
3259            // See if we should be showing the platform update setup UI.
3260            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3261            List<ResolveInfo> ris = mContext.getPackageManager()
3262                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3263
3264            // We don't allow third party apps to replace this.
3265            ResolveInfo ri = null;
3266            for (int i=0; ris != null && i<ris.size(); i++) {
3267                if ((ris.get(i).activityInfo.applicationInfo.flags
3268                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3269                    ri = ris.get(i);
3270                    break;
3271                }
3272            }
3273
3274            if (ri != null) {
3275                String vers = ri.activityInfo.metaData != null
3276                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3277                        : null;
3278                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3279                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3280                            Intent.METADATA_SETUP_VERSION);
3281                }
3282                String lastVers = Settings.Secure.getString(
3283                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3284                if (vers != null && !vers.equals(lastVers)) {
3285                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3286                    intent.setComponent(new ComponentName(
3287                            ri.activityInfo.packageName, ri.activityInfo.name));
3288                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3289                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3290                }
3291            }
3292        }
3293    }
3294
3295    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3296        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3297    }
3298
3299    void enforceNotIsolatedCaller(String caller) {
3300        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3301            throw new SecurityException("Isolated process not allowed to call " + caller);
3302        }
3303    }
3304
3305    @Override
3306    public int getFrontActivityScreenCompatMode() {
3307        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3308        synchronized (this) {
3309            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3310        }
3311    }
3312
3313    @Override
3314    public void setFrontActivityScreenCompatMode(int mode) {
3315        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3316                "setFrontActivityScreenCompatMode");
3317        synchronized (this) {
3318            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3319        }
3320    }
3321
3322    @Override
3323    public int getPackageScreenCompatMode(String packageName) {
3324        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3325        synchronized (this) {
3326            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3327        }
3328    }
3329
3330    @Override
3331    public void setPackageScreenCompatMode(String packageName, int mode) {
3332        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3333                "setPackageScreenCompatMode");
3334        synchronized (this) {
3335            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3336        }
3337    }
3338
3339    @Override
3340    public boolean getPackageAskScreenCompat(String packageName) {
3341        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3342        synchronized (this) {
3343            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3344        }
3345    }
3346
3347    @Override
3348    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3349        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3350                "setPackageAskScreenCompat");
3351        synchronized (this) {
3352            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3353        }
3354    }
3355
3356    private void dispatchProcessesChanged() {
3357        int N;
3358        synchronized (this) {
3359            N = mPendingProcessChanges.size();
3360            if (mActiveProcessChanges.length < N) {
3361                mActiveProcessChanges = new ProcessChangeItem[N];
3362            }
3363            mPendingProcessChanges.toArray(mActiveProcessChanges);
3364            mAvailProcessChanges.addAll(mPendingProcessChanges);
3365            mPendingProcessChanges.clear();
3366            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3367        }
3368
3369        int i = mProcessObservers.beginBroadcast();
3370        while (i > 0) {
3371            i--;
3372            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3373            if (observer != null) {
3374                try {
3375                    for (int j=0; j<N; j++) {
3376                        ProcessChangeItem item = mActiveProcessChanges[j];
3377                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3378                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3379                                    + item.pid + " uid=" + item.uid + ": "
3380                                    + item.foregroundActivities);
3381                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3382                                    item.foregroundActivities);
3383                        }
3384                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3385                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3386                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3387                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3388                        }
3389                    }
3390                } catch (RemoteException e) {
3391                }
3392            }
3393        }
3394        mProcessObservers.finishBroadcast();
3395    }
3396
3397    private void dispatchProcessDied(int pid, int uid) {
3398        int i = mProcessObservers.beginBroadcast();
3399        while (i > 0) {
3400            i--;
3401            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3402            if (observer != null) {
3403                try {
3404                    observer.onProcessDied(pid, uid);
3405                } catch (RemoteException e) {
3406                }
3407            }
3408        }
3409        mProcessObservers.finishBroadcast();
3410    }
3411
3412    @Override
3413    public final int startActivity(IApplicationThread caller, String callingPackage,
3414            Intent intent, String resolvedType, IBinder resultTo,
3415            String resultWho, int requestCode, int startFlags,
3416            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3417        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3418                resultWho, requestCode,
3419                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3420    }
3421
3422    @Override
3423    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3424            Intent intent, String resolvedType, IBinder resultTo,
3425            String resultWho, int requestCode, int startFlags,
3426            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3427        enforceNotIsolatedCaller("startActivity");
3428        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3429                false, ALLOW_FULL_ONLY, "startActivity", null);
3430        // TODO: Switch to user app stacks here.
3431        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3432                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3433                null, null, options, userId, null);
3434    }
3435
3436    @Override
3437    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3438            Intent intent, String resolvedType, IBinder resultTo,
3439            String resultWho, int requestCode, int startFlags, String profileFile,
3440            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3441        enforceNotIsolatedCaller("startActivityAndWait");
3442        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3443                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3444        WaitResult res = new WaitResult();
3445        // TODO: Switch to user app stacks here.
3446        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3447                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3448                res, null, options, userId, null);
3449        return res;
3450    }
3451
3452    @Override
3453    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3454            Intent intent, String resolvedType, IBinder resultTo,
3455            String resultWho, int requestCode, int startFlags, Configuration config,
3456            Bundle options, int userId) {
3457        enforceNotIsolatedCaller("startActivityWithConfig");
3458        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3459                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3460        // TODO: Switch to user app stacks here.
3461        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3462                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3463                null, null, null, config, options, userId, null);
3464        return ret;
3465    }
3466
3467    @Override
3468    public int startActivityIntentSender(IApplicationThread caller,
3469            IntentSender intent, Intent fillInIntent, String resolvedType,
3470            IBinder resultTo, String resultWho, int requestCode,
3471            int flagsMask, int flagsValues, Bundle options) {
3472        enforceNotIsolatedCaller("startActivityIntentSender");
3473        // Refuse possible leaked file descriptors
3474        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3475            throw new IllegalArgumentException("File descriptors passed in Intent");
3476        }
3477
3478        IIntentSender sender = intent.getTarget();
3479        if (!(sender instanceof PendingIntentRecord)) {
3480            throw new IllegalArgumentException("Bad PendingIntent object");
3481        }
3482
3483        PendingIntentRecord pir = (PendingIntentRecord)sender;
3484
3485        synchronized (this) {
3486            // If this is coming from the currently resumed activity, it is
3487            // effectively saying that app switches are allowed at this point.
3488            final ActivityStack stack = getFocusedStack();
3489            if (stack.mResumedActivity != null &&
3490                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3491                mAppSwitchesAllowedTime = 0;
3492            }
3493        }
3494        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3495                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3496        return ret;
3497    }
3498
3499    @Override
3500    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3501            Intent intent, String resolvedType, IVoiceInteractionSession session,
3502            IVoiceInteractor interactor, int startFlags, String profileFile,
3503            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3504        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3505                != PackageManager.PERMISSION_GRANTED) {
3506            String msg = "Permission Denial: startVoiceActivity() from pid="
3507                    + Binder.getCallingPid()
3508                    + ", uid=" + Binder.getCallingUid()
3509                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3510            Slog.w(TAG, msg);
3511            throw new SecurityException(msg);
3512        }
3513        if (session == null || interactor == null) {
3514            throw new NullPointerException("null session or interactor");
3515        }
3516        userId = handleIncomingUser(callingPid, callingUid, userId,
3517                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3518        // TODO: Switch to user app stacks here.
3519        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3520                resolvedType, session, interactor, null, null, 0, startFlags,
3521                profileFile, profileFd, null, null, options, userId, null);
3522    }
3523
3524    @Override
3525    public boolean startNextMatchingActivity(IBinder callingActivity,
3526            Intent intent, Bundle options) {
3527        // Refuse possible leaked file descriptors
3528        if (intent != null && intent.hasFileDescriptors() == true) {
3529            throw new IllegalArgumentException("File descriptors passed in Intent");
3530        }
3531
3532        synchronized (this) {
3533            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3534            if (r == null) {
3535                ActivityOptions.abort(options);
3536                return false;
3537            }
3538            if (r.app == null || r.app.thread == null) {
3539                // The caller is not running...  d'oh!
3540                ActivityOptions.abort(options);
3541                return false;
3542            }
3543            intent = new Intent(intent);
3544            // The caller is not allowed to change the data.
3545            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3546            // And we are resetting to find the next component...
3547            intent.setComponent(null);
3548
3549            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3550
3551            ActivityInfo aInfo = null;
3552            try {
3553                List<ResolveInfo> resolves =
3554                    AppGlobals.getPackageManager().queryIntentActivities(
3555                            intent, r.resolvedType,
3556                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3557                            UserHandle.getCallingUserId());
3558
3559                // Look for the original activity in the list...
3560                final int N = resolves != null ? resolves.size() : 0;
3561                for (int i=0; i<N; i++) {
3562                    ResolveInfo rInfo = resolves.get(i);
3563                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3564                            && rInfo.activityInfo.name.equals(r.info.name)) {
3565                        // We found the current one...  the next matching is
3566                        // after it.
3567                        i++;
3568                        if (i<N) {
3569                            aInfo = resolves.get(i).activityInfo;
3570                        }
3571                        if (debug) {
3572                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3573                                    + "/" + r.info.name);
3574                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3575                                    + "/" + aInfo.name);
3576                        }
3577                        break;
3578                    }
3579                }
3580            } catch (RemoteException e) {
3581            }
3582
3583            if (aInfo == null) {
3584                // Nobody who is next!
3585                ActivityOptions.abort(options);
3586                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3587                return false;
3588            }
3589
3590            intent.setComponent(new ComponentName(
3591                    aInfo.applicationInfo.packageName, aInfo.name));
3592            intent.setFlags(intent.getFlags()&~(
3593                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3594                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3595                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3596                    Intent.FLAG_ACTIVITY_NEW_TASK));
3597
3598            // Okay now we need to start the new activity, replacing the
3599            // currently running activity.  This is a little tricky because
3600            // we want to start the new one as if the current one is finished,
3601            // but not finish the current one first so that there is no flicker.
3602            // And thus...
3603            final boolean wasFinishing = r.finishing;
3604            r.finishing = true;
3605
3606            // Propagate reply information over to the new activity.
3607            final ActivityRecord resultTo = r.resultTo;
3608            final String resultWho = r.resultWho;
3609            final int requestCode = r.requestCode;
3610            r.resultTo = null;
3611            if (resultTo != null) {
3612                resultTo.removeResultsLocked(r, resultWho, requestCode);
3613            }
3614
3615            final long origId = Binder.clearCallingIdentity();
3616            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3617                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3618                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3619                    options, false, null, null);
3620            Binder.restoreCallingIdentity(origId);
3621
3622            r.finishing = wasFinishing;
3623            if (res != ActivityManager.START_SUCCESS) {
3624                return false;
3625            }
3626            return true;
3627        }
3628    }
3629
3630    @Override
3631    public final int startActivityFromRecents(int taskId, Bundle options) {
3632        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3633            String msg = "Permission Denial: startActivityFromRecents called without " +
3634                    START_TASKS_FROM_RECENTS;
3635            Slog.w(TAG, msg);
3636            throw new SecurityException(msg);
3637        }
3638        final int callingUid;
3639        final String callingPackage;
3640        final Intent intent;
3641        final int userId;
3642        synchronized (this) {
3643            final TaskRecord task = recentTaskForIdLocked(taskId);
3644            if (task == null) {
3645                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3646            }
3647            callingUid = task.mCallingUid;
3648            callingPackage = task.mCallingPackage;
3649            intent = task.intent;
3650            userId = task.userId;
3651        }
3652        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3653                options, userId, null);
3654    }
3655
3656    final int startActivityInPackage(int uid, String callingPackage,
3657            Intent intent, String resolvedType, IBinder resultTo,
3658            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3659                    IActivityContainer container) {
3660
3661        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3662                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3663
3664        // TODO: Switch to user app stacks here.
3665        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3666                null, null, resultTo, resultWho, requestCode, startFlags,
3667                null, null, null, null, options, userId, container);
3668        return ret;
3669    }
3670
3671    @Override
3672    public final int startActivities(IApplicationThread caller, String callingPackage,
3673            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3674            int userId) {
3675        enforceNotIsolatedCaller("startActivities");
3676        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3677                false, ALLOW_FULL_ONLY, "startActivity", null);
3678        // TODO: Switch to user app stacks here.
3679        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3680                resolvedTypes, resultTo, options, userId);
3681        return ret;
3682    }
3683
3684    final int startActivitiesInPackage(int uid, String callingPackage,
3685            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3686            Bundle options, int userId) {
3687
3688        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3689                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3690        // TODO: Switch to user app stacks here.
3691        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3692                resultTo, options, userId);
3693        return ret;
3694    }
3695
3696    //explicitly remove thd old information in mRecentTasks when removing existing user.
3697    private void removeRecentTasksForUserLocked(int userId) {
3698        if(userId <= 0) {
3699            Slog.i(TAG, "Can't remove recent task on user " + userId);
3700            return;
3701        }
3702
3703        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3704            TaskRecord tr = mRecentTasks.get(i);
3705            if (tr.userId == userId) {
3706                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3707                        + " when finishing user" + userId);
3708                tr.disposeThumbnail();
3709                mRecentTasks.remove(i);
3710            }
3711        }
3712
3713        // Remove tasks from persistent storage.
3714        mTaskPersister.wakeup(null, true);
3715    }
3716
3717    final void addRecentTaskLocked(TaskRecord task) {
3718        int N = mRecentTasks.size();
3719        // Quick case: check if the top-most recent task is the same.
3720        if (N > 0 && mRecentTasks.get(0) == task) {
3721            return;
3722        }
3723        // Another quick case: never add voice sessions.
3724        if (task.voiceSession != null) {
3725            return;
3726        }
3727        // Remove any existing entries that are the same kind of task.
3728        final Intent intent = task.intent;
3729        final boolean document = intent != null && intent.isDocument();
3730        final ComponentName comp = intent.getComponent();
3731
3732        int maxRecents = task.maxRecents - 1;
3733        for (int i=0; i<N; i++) {
3734            final TaskRecord tr = mRecentTasks.get(i);
3735            if (task != tr) {
3736                if (task.userId != tr.userId) {
3737                    continue;
3738                }
3739                if (i > MAX_RECENT_BITMAPS) {
3740                    tr.freeLastThumbnail();
3741                }
3742                final Intent trIntent = tr.intent;
3743                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3744                    (intent == null || !intent.filterEquals(trIntent))) {
3745                    continue;
3746                }
3747                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3748                if (document && trIsDocument) {
3749                    // These are the same document activity (not necessarily the same doc).
3750                    if (maxRecents > 0) {
3751                        --maxRecents;
3752                        continue;
3753                    }
3754                    // Hit the maximum number of documents for this task. Fall through
3755                    // and remove this document from recents.
3756                } else if (document || trIsDocument) {
3757                    // Only one of these is a document. Not the droid we're looking for.
3758                    continue;
3759                }
3760            }
3761
3762            // Either task and tr are the same or, their affinities match or their intents match
3763            // and neither of them is a document, or they are documents using the same activity
3764            // and their maxRecents has been reached.
3765            tr.disposeThumbnail();
3766            mRecentTasks.remove(i);
3767            if (task != tr) {
3768                tr.closeRecentsChain();
3769            }
3770            i--;
3771            N--;
3772            if (task.intent == null) {
3773                // If the new recent task we are adding is not fully
3774                // specified, then replace it with the existing recent task.
3775                task = tr;
3776            }
3777            notifyTaskPersisterLocked(tr, false);
3778        }
3779        if (N >= MAX_RECENT_TASKS) {
3780            final TaskRecord tr = mRecentTasks.remove(N - 1);
3781            tr.disposeThumbnail();
3782            tr.closeRecentsChain();
3783        }
3784        mRecentTasks.add(0, task);
3785    }
3786
3787    @Override
3788    public void reportActivityFullyDrawn(IBinder token) {
3789        synchronized (this) {
3790            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3791            if (r == null) {
3792                return;
3793            }
3794            r.reportFullyDrawnLocked();
3795        }
3796    }
3797
3798    @Override
3799    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3800        synchronized (this) {
3801            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3802            if (r == null) {
3803                return;
3804            }
3805            final long origId = Binder.clearCallingIdentity();
3806            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3807            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3808                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3809            if (config != null) {
3810                r.frozenBeforeDestroy = true;
3811                if (!updateConfigurationLocked(config, r, false, false)) {
3812                    mStackSupervisor.resumeTopActivitiesLocked();
3813                }
3814            }
3815            Binder.restoreCallingIdentity(origId);
3816        }
3817    }
3818
3819    @Override
3820    public int getRequestedOrientation(IBinder token) {
3821        synchronized (this) {
3822            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3823            if (r == null) {
3824                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3825            }
3826            return mWindowManager.getAppOrientation(r.appToken);
3827        }
3828    }
3829
3830    /**
3831     * This is the internal entry point for handling Activity.finish().
3832     *
3833     * @param token The Binder token referencing the Activity we want to finish.
3834     * @param resultCode Result code, if any, from this Activity.
3835     * @param resultData Result data (Intent), if any, from this Activity.
3836     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3837     *            the root Activity in the task.
3838     *
3839     * @return Returns true if the activity successfully finished, or false if it is still running.
3840     */
3841    @Override
3842    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3843            boolean finishTask) {
3844        // Refuse possible leaked file descriptors
3845        if (resultData != null && resultData.hasFileDescriptors() == true) {
3846            throw new IllegalArgumentException("File descriptors passed in Intent");
3847        }
3848
3849        synchronized(this) {
3850            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3851            if (r == null) {
3852                return true;
3853            }
3854            // Keep track of the root activity of the task before we finish it
3855            TaskRecord tr = r.task;
3856            ActivityRecord rootR = tr.getRootActivity();
3857            // Do not allow task to finish in Lock Task mode.
3858            if (tr == mStackSupervisor.mLockTaskModeTask) {
3859                if (rootR == r) {
3860                    mStackSupervisor.showLockTaskToast();
3861                    return false;
3862                }
3863            }
3864            if (mController != null) {
3865                // Find the first activity that is not finishing.
3866                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3867                if (next != null) {
3868                    // ask watcher if this is allowed
3869                    boolean resumeOK = true;
3870                    try {
3871                        resumeOK = mController.activityResuming(next.packageName);
3872                    } catch (RemoteException e) {
3873                        mController = null;
3874                        Watchdog.getInstance().setActivityController(null);
3875                    }
3876
3877                    if (!resumeOK) {
3878                        return false;
3879                    }
3880                }
3881            }
3882            final long origId = Binder.clearCallingIdentity();
3883            try {
3884                boolean res;
3885                if (finishTask && r == rootR) {
3886                    // If requested, remove the task that is associated to this activity only if it
3887                    // was the root activity in the task.  The result code and data is ignored because
3888                    // we don't support returning them across task boundaries.
3889                    res = removeTaskByIdLocked(tr.taskId, 0);
3890                } else {
3891                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3892                            resultData, "app-request", true);
3893                }
3894                return res;
3895            } finally {
3896                Binder.restoreCallingIdentity(origId);
3897            }
3898        }
3899    }
3900
3901    @Override
3902    public final void finishHeavyWeightApp() {
3903        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3904                != PackageManager.PERMISSION_GRANTED) {
3905            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3906                    + Binder.getCallingPid()
3907                    + ", uid=" + Binder.getCallingUid()
3908                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3909            Slog.w(TAG, msg);
3910            throw new SecurityException(msg);
3911        }
3912
3913        synchronized(this) {
3914            if (mHeavyWeightProcess == null) {
3915                return;
3916            }
3917
3918            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3919                    mHeavyWeightProcess.activities);
3920            for (int i=0; i<activities.size(); i++) {
3921                ActivityRecord r = activities.get(i);
3922                if (!r.finishing) {
3923                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3924                            null, "finish-heavy", true);
3925                }
3926            }
3927
3928            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3929                    mHeavyWeightProcess.userId, 0));
3930            mHeavyWeightProcess = null;
3931        }
3932    }
3933
3934    @Override
3935    public void crashApplication(int uid, int initialPid, String packageName,
3936            String message) {
3937        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3938                != PackageManager.PERMISSION_GRANTED) {
3939            String msg = "Permission Denial: crashApplication() from pid="
3940                    + Binder.getCallingPid()
3941                    + ", uid=" + Binder.getCallingUid()
3942                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3943            Slog.w(TAG, msg);
3944            throw new SecurityException(msg);
3945        }
3946
3947        synchronized(this) {
3948            ProcessRecord proc = null;
3949
3950            // Figure out which process to kill.  We don't trust that initialPid
3951            // still has any relation to current pids, so must scan through the
3952            // list.
3953            synchronized (mPidsSelfLocked) {
3954                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3955                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3956                    if (p.uid != uid) {
3957                        continue;
3958                    }
3959                    if (p.pid == initialPid) {
3960                        proc = p;
3961                        break;
3962                    }
3963                    if (p.pkgList.containsKey(packageName)) {
3964                        proc = p;
3965                    }
3966                }
3967            }
3968
3969            if (proc == null) {
3970                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3971                        + " initialPid=" + initialPid
3972                        + " packageName=" + packageName);
3973                return;
3974            }
3975
3976            if (proc.thread != null) {
3977                if (proc.pid == Process.myPid()) {
3978                    Log.w(TAG, "crashApplication: trying to crash self!");
3979                    return;
3980                }
3981                long ident = Binder.clearCallingIdentity();
3982                try {
3983                    proc.thread.scheduleCrash(message);
3984                } catch (RemoteException e) {
3985                }
3986                Binder.restoreCallingIdentity(ident);
3987            }
3988        }
3989    }
3990
3991    @Override
3992    public final void finishSubActivity(IBinder token, String resultWho,
3993            int requestCode) {
3994        synchronized(this) {
3995            final long origId = Binder.clearCallingIdentity();
3996            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3997            if (r != null) {
3998                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3999            }
4000            Binder.restoreCallingIdentity(origId);
4001        }
4002    }
4003
4004    @Override
4005    public boolean finishActivityAffinity(IBinder token) {
4006        synchronized(this) {
4007            final long origId = Binder.clearCallingIdentity();
4008            try {
4009                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4010
4011                ActivityRecord rootR = r.task.getRootActivity();
4012                // Do not allow task to finish in Lock Task mode.
4013                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4014                    if (rootR == r) {
4015                        mStackSupervisor.showLockTaskToast();
4016                        return false;
4017                    }
4018                }
4019                boolean res = false;
4020                if (r != null) {
4021                    res = r.task.stack.finishActivityAffinityLocked(r);
4022                }
4023                return res;
4024            } finally {
4025                Binder.restoreCallingIdentity(origId);
4026            }
4027        }
4028    }
4029
4030    @Override
4031    public void finishVoiceTask(IVoiceInteractionSession session) {
4032        synchronized(this) {
4033            final long origId = Binder.clearCallingIdentity();
4034            try {
4035                mStackSupervisor.finishVoiceTask(session);
4036            } finally {
4037                Binder.restoreCallingIdentity(origId);
4038            }
4039        }
4040
4041    }
4042
4043    @Override
4044    public boolean willActivityBeVisible(IBinder token) {
4045        synchronized(this) {
4046            ActivityStack stack = ActivityRecord.getStackLocked(token);
4047            if (stack != null) {
4048                return stack.willActivityBeVisibleLocked(token);
4049            }
4050            return false;
4051        }
4052    }
4053
4054    @Override
4055    public void overridePendingTransition(IBinder token, String packageName,
4056            int enterAnim, int exitAnim) {
4057        synchronized(this) {
4058            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4059            if (self == null) {
4060                return;
4061            }
4062
4063            final long origId = Binder.clearCallingIdentity();
4064
4065            if (self.state == ActivityState.RESUMED
4066                    || self.state == ActivityState.PAUSING) {
4067                mWindowManager.overridePendingAppTransition(packageName,
4068                        enterAnim, exitAnim, null);
4069            }
4070
4071            Binder.restoreCallingIdentity(origId);
4072        }
4073    }
4074
4075    /**
4076     * Main function for removing an existing process from the activity manager
4077     * as a result of that process going away.  Clears out all connections
4078     * to the process.
4079     */
4080    private final void handleAppDiedLocked(ProcessRecord app,
4081            boolean restarting, boolean allowRestart) {
4082        int pid = app.pid;
4083        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4084        if (!restarting) {
4085            removeLruProcessLocked(app);
4086            if (pid > 0) {
4087                ProcessList.remove(pid);
4088            }
4089        }
4090
4091        if (mProfileProc == app) {
4092            clearProfilerLocked();
4093        }
4094
4095        // Remove this application's activities from active lists.
4096        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4097
4098        app.activities.clear();
4099
4100        if (app.instrumentationClass != null) {
4101            Slog.w(TAG, "Crash of app " + app.processName
4102                  + " running instrumentation " + app.instrumentationClass);
4103            Bundle info = new Bundle();
4104            info.putString("shortMsg", "Process crashed.");
4105            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4106        }
4107
4108        if (!restarting) {
4109            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4110                // If there was nothing to resume, and we are not already
4111                // restarting this process, but there is a visible activity that
4112                // is hosted by the process...  then make sure all visible
4113                // activities are running, taking care of restarting this
4114                // process.
4115                if (hasVisibleActivities) {
4116                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4117                }
4118            }
4119        }
4120    }
4121
4122    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4123        IBinder threadBinder = thread.asBinder();
4124        // Find the application record.
4125        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4126            ProcessRecord rec = mLruProcesses.get(i);
4127            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4128                return i;
4129            }
4130        }
4131        return -1;
4132    }
4133
4134    final ProcessRecord getRecordForAppLocked(
4135            IApplicationThread thread) {
4136        if (thread == null) {
4137            return null;
4138        }
4139
4140        int appIndex = getLRURecordIndexForAppLocked(thread);
4141        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4142    }
4143
4144    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4145        // If there are no longer any background processes running,
4146        // and the app that died was not running instrumentation,
4147        // then tell everyone we are now low on memory.
4148        boolean haveBg = false;
4149        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4150            ProcessRecord rec = mLruProcesses.get(i);
4151            if (rec.thread != null
4152                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4153                haveBg = true;
4154                break;
4155            }
4156        }
4157
4158        if (!haveBg) {
4159            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4160            if (doReport) {
4161                long now = SystemClock.uptimeMillis();
4162                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4163                    doReport = false;
4164                } else {
4165                    mLastMemUsageReportTime = now;
4166                }
4167            }
4168            final ArrayList<ProcessMemInfo> memInfos
4169                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4170            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4171            long now = SystemClock.uptimeMillis();
4172            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4173                ProcessRecord rec = mLruProcesses.get(i);
4174                if (rec == dyingProc || rec.thread == null) {
4175                    continue;
4176                }
4177                if (doReport) {
4178                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4179                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4180                }
4181                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4182                    // The low memory report is overriding any current
4183                    // state for a GC request.  Make sure to do
4184                    // heavy/important/visible/foreground processes first.
4185                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4186                        rec.lastRequestedGc = 0;
4187                    } else {
4188                        rec.lastRequestedGc = rec.lastLowMemory;
4189                    }
4190                    rec.reportLowMemory = true;
4191                    rec.lastLowMemory = now;
4192                    mProcessesToGc.remove(rec);
4193                    addProcessToGcListLocked(rec);
4194                }
4195            }
4196            if (doReport) {
4197                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4198                mHandler.sendMessage(msg);
4199            }
4200            scheduleAppGcsLocked();
4201        }
4202    }
4203
4204    final void appDiedLocked(ProcessRecord app, int pid,
4205            IApplicationThread thread) {
4206
4207        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4208        synchronized (stats) {
4209            stats.noteProcessDiedLocked(app.info.uid, pid);
4210        }
4211
4212        Process.killProcessGroup(app.info.uid, pid);
4213
4214        // Clean up already done if the process has been re-started.
4215        if (app.pid == pid && app.thread != null &&
4216                app.thread.asBinder() == thread.asBinder()) {
4217            boolean doLowMem = app.instrumentationClass == null;
4218            boolean doOomAdj = doLowMem;
4219            if (!app.killedByAm) {
4220                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4221                        + ") has died.");
4222                mAllowLowerMemLevel = true;
4223            } else {
4224                // Note that we always want to do oom adj to update our state with the
4225                // new number of procs.
4226                mAllowLowerMemLevel = false;
4227                doLowMem = false;
4228            }
4229            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4230            if (DEBUG_CLEANUP) Slog.v(
4231                TAG, "Dying app: " + app + ", pid: " + pid
4232                + ", thread: " + thread.asBinder());
4233            handleAppDiedLocked(app, false, true);
4234
4235            if (doOomAdj) {
4236                updateOomAdjLocked();
4237            }
4238            if (doLowMem) {
4239                doLowMemReportIfNeededLocked(app);
4240            }
4241        } else if (app.pid != pid) {
4242            // A new process has already been started.
4243            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4244                    + ") has died and restarted (pid " + app.pid + ").");
4245            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4246        } else if (DEBUG_PROCESSES) {
4247            Slog.d(TAG, "Received spurious death notification for thread "
4248                    + thread.asBinder());
4249        }
4250    }
4251
4252    /**
4253     * If a stack trace dump file is configured, dump process stack traces.
4254     * @param clearTraces causes the dump file to be erased prior to the new
4255     *    traces being written, if true; when false, the new traces will be
4256     *    appended to any existing file content.
4257     * @param firstPids of dalvik VM processes to dump stack traces for first
4258     * @param lastPids of dalvik VM processes to dump stack traces for last
4259     * @param nativeProcs optional list of native process names to dump stack crawls
4260     * @return file containing stack traces, or null if no dump file is configured
4261     */
4262    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4263            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4264        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4265        if (tracesPath == null || tracesPath.length() == 0) {
4266            return null;
4267        }
4268
4269        File tracesFile = new File(tracesPath);
4270        try {
4271            File tracesDir = tracesFile.getParentFile();
4272            if (!tracesDir.exists()) {
4273                tracesFile.mkdirs();
4274                if (!SELinux.restorecon(tracesDir)) {
4275                    return null;
4276                }
4277            }
4278            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4279
4280            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4281            tracesFile.createNewFile();
4282            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4283        } catch (IOException e) {
4284            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4285            return null;
4286        }
4287
4288        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4289        return tracesFile;
4290    }
4291
4292    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4293            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4294        // Use a FileObserver to detect when traces finish writing.
4295        // The order of traces is considered important to maintain for legibility.
4296        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4297            @Override
4298            public synchronized void onEvent(int event, String path) { notify(); }
4299        };
4300
4301        try {
4302            observer.startWatching();
4303
4304            // First collect all of the stacks of the most important pids.
4305            if (firstPids != null) {
4306                try {
4307                    int num = firstPids.size();
4308                    for (int i = 0; i < num; i++) {
4309                        synchronized (observer) {
4310                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4311                            observer.wait(200);  // Wait for write-close, give up after 200msec
4312                        }
4313                    }
4314                } catch (InterruptedException e) {
4315                    Log.wtf(TAG, e);
4316                }
4317            }
4318
4319            // Next collect the stacks of the native pids
4320            if (nativeProcs != null) {
4321                int[] pids = Process.getPidsForCommands(nativeProcs);
4322                if (pids != null) {
4323                    for (int pid : pids) {
4324                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4325                    }
4326                }
4327            }
4328
4329            // Lastly, measure CPU usage.
4330            if (processCpuTracker != null) {
4331                processCpuTracker.init();
4332                System.gc();
4333                processCpuTracker.update();
4334                try {
4335                    synchronized (processCpuTracker) {
4336                        processCpuTracker.wait(500); // measure over 1/2 second.
4337                    }
4338                } catch (InterruptedException e) {
4339                }
4340                processCpuTracker.update();
4341
4342                // We'll take the stack crawls of just the top apps using CPU.
4343                final int N = processCpuTracker.countWorkingStats();
4344                int numProcs = 0;
4345                for (int i=0; i<N && numProcs<5; i++) {
4346                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4347                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4348                        numProcs++;
4349                        try {
4350                            synchronized (observer) {
4351                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4352                                observer.wait(200);  // Wait for write-close, give up after 200msec
4353                            }
4354                        } catch (InterruptedException e) {
4355                            Log.wtf(TAG, e);
4356                        }
4357
4358                    }
4359                }
4360            }
4361        } finally {
4362            observer.stopWatching();
4363        }
4364    }
4365
4366    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4367        if (true || IS_USER_BUILD) {
4368            return;
4369        }
4370        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4371        if (tracesPath == null || tracesPath.length() == 0) {
4372            return;
4373        }
4374
4375        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4376        StrictMode.allowThreadDiskWrites();
4377        try {
4378            final File tracesFile = new File(tracesPath);
4379            final File tracesDir = tracesFile.getParentFile();
4380            final File tracesTmp = new File(tracesDir, "__tmp__");
4381            try {
4382                if (!tracesDir.exists()) {
4383                    tracesFile.mkdirs();
4384                    if (!SELinux.restorecon(tracesDir.getPath())) {
4385                        return;
4386                    }
4387                }
4388                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4389
4390                if (tracesFile.exists()) {
4391                    tracesTmp.delete();
4392                    tracesFile.renameTo(tracesTmp);
4393                }
4394                StringBuilder sb = new StringBuilder();
4395                Time tobj = new Time();
4396                tobj.set(System.currentTimeMillis());
4397                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4398                sb.append(": ");
4399                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4400                sb.append(" since ");
4401                sb.append(msg);
4402                FileOutputStream fos = new FileOutputStream(tracesFile);
4403                fos.write(sb.toString().getBytes());
4404                if (app == null) {
4405                    fos.write("\n*** No application process!".getBytes());
4406                }
4407                fos.close();
4408                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4409            } catch (IOException e) {
4410                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4411                return;
4412            }
4413
4414            if (app != null) {
4415                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4416                firstPids.add(app.pid);
4417                dumpStackTraces(tracesPath, firstPids, null, null, null);
4418            }
4419
4420            File lastTracesFile = null;
4421            File curTracesFile = null;
4422            for (int i=9; i>=0; i--) {
4423                String name = String.format(Locale.US, "slow%02d.txt", i);
4424                curTracesFile = new File(tracesDir, name);
4425                if (curTracesFile.exists()) {
4426                    if (lastTracesFile != null) {
4427                        curTracesFile.renameTo(lastTracesFile);
4428                    } else {
4429                        curTracesFile.delete();
4430                    }
4431                }
4432                lastTracesFile = curTracesFile;
4433            }
4434            tracesFile.renameTo(curTracesFile);
4435            if (tracesTmp.exists()) {
4436                tracesTmp.renameTo(tracesFile);
4437            }
4438        } finally {
4439            StrictMode.setThreadPolicy(oldPolicy);
4440        }
4441    }
4442
4443    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4444            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4445        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4446        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4447
4448        if (mController != null) {
4449            try {
4450                // 0 == continue, -1 = kill process immediately
4451                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4452                if (res < 0 && app.pid != MY_PID) {
4453                    Process.killProcess(app.pid);
4454                    Process.killProcessGroup(app.info.uid, app.pid);
4455                }
4456            } catch (RemoteException e) {
4457                mController = null;
4458                Watchdog.getInstance().setActivityController(null);
4459            }
4460        }
4461
4462        long anrTime = SystemClock.uptimeMillis();
4463        if (MONITOR_CPU_USAGE) {
4464            updateCpuStatsNow();
4465        }
4466
4467        synchronized (this) {
4468            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4469            if (mShuttingDown) {
4470                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4471                return;
4472            } else if (app.notResponding) {
4473                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4474                return;
4475            } else if (app.crashing) {
4476                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4477                return;
4478            }
4479
4480            // In case we come through here for the same app before completing
4481            // this one, mark as anring now so we will bail out.
4482            app.notResponding = true;
4483
4484            // Log the ANR to the event log.
4485            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4486                    app.processName, app.info.flags, annotation);
4487
4488            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4489            firstPids.add(app.pid);
4490
4491            int parentPid = app.pid;
4492            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4493            if (parentPid != app.pid) firstPids.add(parentPid);
4494
4495            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4496
4497            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4498                ProcessRecord r = mLruProcesses.get(i);
4499                if (r != null && r.thread != null) {
4500                    int pid = r.pid;
4501                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4502                        if (r.persistent) {
4503                            firstPids.add(pid);
4504                        } else {
4505                            lastPids.put(pid, Boolean.TRUE);
4506                        }
4507                    }
4508                }
4509            }
4510        }
4511
4512        // Log the ANR to the main log.
4513        StringBuilder info = new StringBuilder();
4514        info.setLength(0);
4515        info.append("ANR in ").append(app.processName);
4516        if (activity != null && activity.shortComponentName != null) {
4517            info.append(" (").append(activity.shortComponentName).append(")");
4518        }
4519        info.append("\n");
4520        info.append("PID: ").append(app.pid).append("\n");
4521        if (annotation != null) {
4522            info.append("Reason: ").append(annotation).append("\n");
4523        }
4524        if (parent != null && parent != activity) {
4525            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4526        }
4527
4528        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4529
4530        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4531                NATIVE_STACKS_OF_INTEREST);
4532
4533        String cpuInfo = null;
4534        if (MONITOR_CPU_USAGE) {
4535            updateCpuStatsNow();
4536            synchronized (mProcessCpuThread) {
4537                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4538            }
4539            info.append(processCpuTracker.printCurrentLoad());
4540            info.append(cpuInfo);
4541        }
4542
4543        info.append(processCpuTracker.printCurrentState(anrTime));
4544
4545        Slog.e(TAG, info.toString());
4546        if (tracesFile == null) {
4547            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4548            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4549        }
4550
4551        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4552                cpuInfo, tracesFile, null);
4553
4554        if (mController != null) {
4555            try {
4556                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4557                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4558                if (res != 0) {
4559                    if (res < 0 && app.pid != MY_PID) {
4560                        Process.killProcess(app.pid);
4561                        Process.killProcessGroup(app.info.uid, app.pid);
4562                    } else {
4563                        synchronized (this) {
4564                            mServices.scheduleServiceTimeoutLocked(app);
4565                        }
4566                    }
4567                    return;
4568                }
4569            } catch (RemoteException e) {
4570                mController = null;
4571                Watchdog.getInstance().setActivityController(null);
4572            }
4573        }
4574
4575        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4576        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4577                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4578
4579        synchronized (this) {
4580            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4581                killUnneededProcessLocked(app, "background ANR");
4582                return;
4583            }
4584
4585            // Set the app's notResponding state, and look up the errorReportReceiver
4586            makeAppNotRespondingLocked(app,
4587                    activity != null ? activity.shortComponentName : null,
4588                    annotation != null ? "ANR " + annotation : "ANR",
4589                    info.toString());
4590
4591            // Bring up the infamous App Not Responding dialog
4592            Message msg = Message.obtain();
4593            HashMap<String, Object> map = new HashMap<String, Object>();
4594            msg.what = SHOW_NOT_RESPONDING_MSG;
4595            msg.obj = map;
4596            msg.arg1 = aboveSystem ? 1 : 0;
4597            map.put("app", app);
4598            if (activity != null) {
4599                map.put("activity", activity);
4600            }
4601
4602            mHandler.sendMessage(msg);
4603        }
4604    }
4605
4606    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4607        if (!mLaunchWarningShown) {
4608            mLaunchWarningShown = true;
4609            mHandler.post(new Runnable() {
4610                @Override
4611                public void run() {
4612                    synchronized (ActivityManagerService.this) {
4613                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4614                        d.show();
4615                        mHandler.postDelayed(new Runnable() {
4616                            @Override
4617                            public void run() {
4618                                synchronized (ActivityManagerService.this) {
4619                                    d.dismiss();
4620                                    mLaunchWarningShown = false;
4621                                }
4622                            }
4623                        }, 4000);
4624                    }
4625                }
4626            });
4627        }
4628    }
4629
4630    @Override
4631    public boolean clearApplicationUserData(final String packageName,
4632            final IPackageDataObserver observer, int userId) {
4633        enforceNotIsolatedCaller("clearApplicationUserData");
4634        int uid = Binder.getCallingUid();
4635        int pid = Binder.getCallingPid();
4636        userId = handleIncomingUser(pid, uid,
4637                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4638        long callingId = Binder.clearCallingIdentity();
4639        try {
4640            IPackageManager pm = AppGlobals.getPackageManager();
4641            int pkgUid = -1;
4642            synchronized(this) {
4643                try {
4644                    pkgUid = pm.getPackageUid(packageName, userId);
4645                } catch (RemoteException e) {
4646                }
4647                if (pkgUid == -1) {
4648                    Slog.w(TAG, "Invalid packageName: " + packageName);
4649                    if (observer != null) {
4650                        try {
4651                            observer.onRemoveCompleted(packageName, false);
4652                        } catch (RemoteException e) {
4653                            Slog.i(TAG, "Observer no longer exists.");
4654                        }
4655                    }
4656                    return false;
4657                }
4658                if (uid == pkgUid || checkComponentPermission(
4659                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4660                        pid, uid, -1, true)
4661                        == PackageManager.PERMISSION_GRANTED) {
4662                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4663                } else {
4664                    throw new SecurityException("PID " + pid + " does not have permission "
4665                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4666                                    + " of package " + packageName);
4667                }
4668            }
4669
4670            try {
4671                // Clear application user data
4672                pm.clearApplicationUserData(packageName, observer, userId);
4673
4674                // Remove all permissions granted from/to this package
4675                removeUriPermissionsForPackageLocked(packageName, userId, true);
4676
4677                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4678                        Uri.fromParts("package", packageName, null));
4679                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4680                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4681                        null, null, 0, null, null, null, false, false, userId);
4682            } catch (RemoteException e) {
4683            }
4684        } finally {
4685            Binder.restoreCallingIdentity(callingId);
4686        }
4687        return true;
4688    }
4689
4690    @Override
4691    public void killBackgroundProcesses(final String packageName, int userId) {
4692        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4693                != PackageManager.PERMISSION_GRANTED &&
4694                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4695                        != PackageManager.PERMISSION_GRANTED) {
4696            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4697                    + Binder.getCallingPid()
4698                    + ", uid=" + Binder.getCallingUid()
4699                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4700            Slog.w(TAG, msg);
4701            throw new SecurityException(msg);
4702        }
4703
4704        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4705                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4706        long callingId = Binder.clearCallingIdentity();
4707        try {
4708            IPackageManager pm = AppGlobals.getPackageManager();
4709            synchronized(this) {
4710                int appId = -1;
4711                try {
4712                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4713                } catch (RemoteException e) {
4714                }
4715                if (appId == -1) {
4716                    Slog.w(TAG, "Invalid packageName: " + packageName);
4717                    return;
4718                }
4719                killPackageProcessesLocked(packageName, appId, userId,
4720                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4721            }
4722        } finally {
4723            Binder.restoreCallingIdentity(callingId);
4724        }
4725    }
4726
4727    @Override
4728    public void killAllBackgroundProcesses() {
4729        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4730                != PackageManager.PERMISSION_GRANTED) {
4731            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4732                    + Binder.getCallingPid()
4733                    + ", uid=" + Binder.getCallingUid()
4734                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4735            Slog.w(TAG, msg);
4736            throw new SecurityException(msg);
4737        }
4738
4739        long callingId = Binder.clearCallingIdentity();
4740        try {
4741            synchronized(this) {
4742                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4743                final int NP = mProcessNames.getMap().size();
4744                for (int ip=0; ip<NP; ip++) {
4745                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4746                    final int NA = apps.size();
4747                    for (int ia=0; ia<NA; ia++) {
4748                        ProcessRecord app = apps.valueAt(ia);
4749                        if (app.persistent) {
4750                            // we don't kill persistent processes
4751                            continue;
4752                        }
4753                        if (app.removed) {
4754                            procs.add(app);
4755                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4756                            app.removed = true;
4757                            procs.add(app);
4758                        }
4759                    }
4760                }
4761
4762                int N = procs.size();
4763                for (int i=0; i<N; i++) {
4764                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4765                }
4766                mAllowLowerMemLevel = true;
4767                updateOomAdjLocked();
4768                doLowMemReportIfNeededLocked(null);
4769            }
4770        } finally {
4771            Binder.restoreCallingIdentity(callingId);
4772        }
4773    }
4774
4775    @Override
4776    public void forceStopPackage(final String packageName, int userId) {
4777        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4778                != PackageManager.PERMISSION_GRANTED) {
4779            String msg = "Permission Denial: forceStopPackage() from pid="
4780                    + Binder.getCallingPid()
4781                    + ", uid=" + Binder.getCallingUid()
4782                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4783            Slog.w(TAG, msg);
4784            throw new SecurityException(msg);
4785        }
4786        final int callingPid = Binder.getCallingPid();
4787        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4788                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4789        long callingId = Binder.clearCallingIdentity();
4790        try {
4791            IPackageManager pm = AppGlobals.getPackageManager();
4792            synchronized(this) {
4793                int[] users = userId == UserHandle.USER_ALL
4794                        ? getUsersLocked() : new int[] { userId };
4795                for (int user : users) {
4796                    int pkgUid = -1;
4797                    try {
4798                        pkgUid = pm.getPackageUid(packageName, user);
4799                    } catch (RemoteException e) {
4800                    }
4801                    if (pkgUid == -1) {
4802                        Slog.w(TAG, "Invalid packageName: " + packageName);
4803                        continue;
4804                    }
4805                    try {
4806                        pm.setPackageStoppedState(packageName, true, user);
4807                    } catch (RemoteException e) {
4808                    } catch (IllegalArgumentException e) {
4809                        Slog.w(TAG, "Failed trying to unstop package "
4810                                + packageName + ": " + e);
4811                    }
4812                    if (isUserRunningLocked(user, false)) {
4813                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4814                    }
4815                }
4816            }
4817        } finally {
4818            Binder.restoreCallingIdentity(callingId);
4819        }
4820    }
4821
4822    @Override
4823    public void addPackageDependency(String packageName) {
4824        synchronized (this) {
4825            int callingPid = Binder.getCallingPid();
4826            if (callingPid == Process.myPid()) {
4827                //  Yeah, um, no.
4828                Slog.w(TAG, "Can't addPackageDependency on system process");
4829                return;
4830            }
4831            ProcessRecord proc;
4832            synchronized (mPidsSelfLocked) {
4833                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4834            }
4835            if (proc != null) {
4836                if (proc.pkgDeps == null) {
4837                    proc.pkgDeps = new ArraySet<String>(1);
4838                }
4839                proc.pkgDeps.add(packageName);
4840            }
4841        }
4842    }
4843
4844    /*
4845     * The pkg name and app id have to be specified.
4846     */
4847    @Override
4848    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4849        if (pkg == null) {
4850            return;
4851        }
4852        // Make sure the uid is valid.
4853        if (appid < 0) {
4854            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4855            return;
4856        }
4857        int callerUid = Binder.getCallingUid();
4858        // Only the system server can kill an application
4859        if (callerUid == Process.SYSTEM_UID) {
4860            // Post an aysnc message to kill the application
4861            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4862            msg.arg1 = appid;
4863            msg.arg2 = 0;
4864            Bundle bundle = new Bundle();
4865            bundle.putString("pkg", pkg);
4866            bundle.putString("reason", reason);
4867            msg.obj = bundle;
4868            mHandler.sendMessage(msg);
4869        } else {
4870            throw new SecurityException(callerUid + " cannot kill pkg: " +
4871                    pkg);
4872        }
4873    }
4874
4875    @Override
4876    public void closeSystemDialogs(String reason) {
4877        enforceNotIsolatedCaller("closeSystemDialogs");
4878
4879        final int pid = Binder.getCallingPid();
4880        final int uid = Binder.getCallingUid();
4881        final long origId = Binder.clearCallingIdentity();
4882        try {
4883            synchronized (this) {
4884                // Only allow this from foreground processes, so that background
4885                // applications can't abuse it to prevent system UI from being shown.
4886                if (uid >= Process.FIRST_APPLICATION_UID) {
4887                    ProcessRecord proc;
4888                    synchronized (mPidsSelfLocked) {
4889                        proc = mPidsSelfLocked.get(pid);
4890                    }
4891                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4892                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4893                                + " from background process " + proc);
4894                        return;
4895                    }
4896                }
4897                closeSystemDialogsLocked(reason);
4898            }
4899        } finally {
4900            Binder.restoreCallingIdentity(origId);
4901        }
4902    }
4903
4904    void closeSystemDialogsLocked(String reason) {
4905        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4906        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4907                | Intent.FLAG_RECEIVER_FOREGROUND);
4908        if (reason != null) {
4909            intent.putExtra("reason", reason);
4910        }
4911        mWindowManager.closeSystemDialogs(reason);
4912
4913        mStackSupervisor.closeSystemDialogsLocked();
4914
4915        broadcastIntentLocked(null, null, intent, null,
4916                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4917                Process.SYSTEM_UID, UserHandle.USER_ALL);
4918    }
4919
4920    @Override
4921    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4922        enforceNotIsolatedCaller("getProcessMemoryInfo");
4923        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4924        for (int i=pids.length-1; i>=0; i--) {
4925            ProcessRecord proc;
4926            int oomAdj;
4927            synchronized (this) {
4928                synchronized (mPidsSelfLocked) {
4929                    proc = mPidsSelfLocked.get(pids[i]);
4930                    oomAdj = proc != null ? proc.setAdj : 0;
4931                }
4932            }
4933            infos[i] = new Debug.MemoryInfo();
4934            Debug.getMemoryInfo(pids[i], infos[i]);
4935            if (proc != null) {
4936                synchronized (this) {
4937                    if (proc.thread != null && proc.setAdj == oomAdj) {
4938                        // Record this for posterity if the process has been stable.
4939                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4940                                infos[i].getTotalUss(), false, proc.pkgList);
4941                    }
4942                }
4943            }
4944        }
4945        return infos;
4946    }
4947
4948    @Override
4949    public long[] getProcessPss(int[] pids) {
4950        enforceNotIsolatedCaller("getProcessPss");
4951        long[] pss = new long[pids.length];
4952        for (int i=pids.length-1; i>=0; i--) {
4953            ProcessRecord proc;
4954            int oomAdj;
4955            synchronized (this) {
4956                synchronized (mPidsSelfLocked) {
4957                    proc = mPidsSelfLocked.get(pids[i]);
4958                    oomAdj = proc != null ? proc.setAdj : 0;
4959                }
4960            }
4961            long[] tmpUss = new long[1];
4962            pss[i] = Debug.getPss(pids[i], tmpUss);
4963            if (proc != null) {
4964                synchronized (this) {
4965                    if (proc.thread != null && proc.setAdj == oomAdj) {
4966                        // Record this for posterity if the process has been stable.
4967                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4968                    }
4969                }
4970            }
4971        }
4972        return pss;
4973    }
4974
4975    @Override
4976    public void killApplicationProcess(String processName, int uid) {
4977        if (processName == null) {
4978            return;
4979        }
4980
4981        int callerUid = Binder.getCallingUid();
4982        // Only the system server can kill an application
4983        if (callerUid == Process.SYSTEM_UID) {
4984            synchronized (this) {
4985                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4986                if (app != null && app.thread != null) {
4987                    try {
4988                        app.thread.scheduleSuicide();
4989                    } catch (RemoteException e) {
4990                        // If the other end already died, then our work here is done.
4991                    }
4992                } else {
4993                    Slog.w(TAG, "Process/uid not found attempting kill of "
4994                            + processName + " / " + uid);
4995                }
4996            }
4997        } else {
4998            throw new SecurityException(callerUid + " cannot kill app process: " +
4999                    processName);
5000        }
5001    }
5002
5003    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5004        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5005                false, true, false, false, UserHandle.getUserId(uid), reason);
5006        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5007                Uri.fromParts("package", packageName, null));
5008        if (!mProcessesReady) {
5009            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5010                    | Intent.FLAG_RECEIVER_FOREGROUND);
5011        }
5012        intent.putExtra(Intent.EXTRA_UID, uid);
5013        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5014        broadcastIntentLocked(null, null, intent,
5015                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5016                false, false,
5017                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5018    }
5019
5020    private void forceStopUserLocked(int userId, String reason) {
5021        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5022        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5023        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5024                | Intent.FLAG_RECEIVER_FOREGROUND);
5025        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5026        broadcastIntentLocked(null, null, intent,
5027                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5028                false, false,
5029                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5030    }
5031
5032    private final boolean killPackageProcessesLocked(String packageName, int appId,
5033            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5034            boolean doit, boolean evenPersistent, String reason) {
5035        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5036
5037        // Remove all processes this package may have touched: all with the
5038        // same UID (except for the system or root user), and all whose name
5039        // matches the package name.
5040        final int NP = mProcessNames.getMap().size();
5041        for (int ip=0; ip<NP; ip++) {
5042            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5043            final int NA = apps.size();
5044            for (int ia=0; ia<NA; ia++) {
5045                ProcessRecord app = apps.valueAt(ia);
5046                if (app.persistent && !evenPersistent) {
5047                    // we don't kill persistent processes
5048                    continue;
5049                }
5050                if (app.removed) {
5051                    if (doit) {
5052                        procs.add(app);
5053                    }
5054                    continue;
5055                }
5056
5057                // Skip process if it doesn't meet our oom adj requirement.
5058                if (app.setAdj < minOomAdj) {
5059                    continue;
5060                }
5061
5062                // If no package is specified, we call all processes under the
5063                // give user id.
5064                if (packageName == null) {
5065                    if (app.userId != userId) {
5066                        continue;
5067                    }
5068                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5069                        continue;
5070                    }
5071                // Package has been specified, we want to hit all processes
5072                // that match it.  We need to qualify this by the processes
5073                // that are running under the specified app and user ID.
5074                } else {
5075                    final boolean isDep = app.pkgDeps != null
5076                            && app.pkgDeps.contains(packageName);
5077                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5078                        continue;
5079                    }
5080                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5081                        continue;
5082                    }
5083                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5084                        continue;
5085                    }
5086                }
5087
5088                // Process has passed all conditions, kill it!
5089                if (!doit) {
5090                    return true;
5091                }
5092                app.removed = true;
5093                procs.add(app);
5094            }
5095        }
5096
5097        int N = procs.size();
5098        for (int i=0; i<N; i++) {
5099            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5100        }
5101        updateOomAdjLocked();
5102        return N > 0;
5103    }
5104
5105    private final boolean forceStopPackageLocked(String name, int appId,
5106            boolean callerWillRestart, boolean purgeCache, boolean doit,
5107            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5108        int i;
5109        int N;
5110
5111        if (userId == UserHandle.USER_ALL && name == null) {
5112            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5113        }
5114
5115        if (appId < 0 && name != null) {
5116            try {
5117                appId = UserHandle.getAppId(
5118                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5119            } catch (RemoteException e) {
5120            }
5121        }
5122
5123        if (doit) {
5124            if (name != null) {
5125                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5126                        + " user=" + userId + ": " + reason);
5127            } else {
5128                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5129            }
5130
5131            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5132            for (int ip=pmap.size()-1; ip>=0; ip--) {
5133                SparseArray<Long> ba = pmap.valueAt(ip);
5134                for (i=ba.size()-1; i>=0; i--) {
5135                    boolean remove = false;
5136                    final int entUid = ba.keyAt(i);
5137                    if (name != null) {
5138                        if (userId == UserHandle.USER_ALL) {
5139                            if (UserHandle.getAppId(entUid) == appId) {
5140                                remove = true;
5141                            }
5142                        } else {
5143                            if (entUid == UserHandle.getUid(userId, appId)) {
5144                                remove = true;
5145                            }
5146                        }
5147                    } else if (UserHandle.getUserId(entUid) == userId) {
5148                        remove = true;
5149                    }
5150                    if (remove) {
5151                        ba.removeAt(i);
5152                    }
5153                }
5154                if (ba.size() == 0) {
5155                    pmap.removeAt(ip);
5156                }
5157            }
5158        }
5159
5160        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5161                -100, callerWillRestart, true, doit, evenPersistent,
5162                name == null ? ("stop user " + userId) : ("stop " + name));
5163
5164        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5165            if (!doit) {
5166                return true;
5167            }
5168            didSomething = true;
5169        }
5170
5171        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5172            if (!doit) {
5173                return true;
5174            }
5175            didSomething = true;
5176        }
5177
5178        if (name == null) {
5179            // Remove all sticky broadcasts from this user.
5180            mStickyBroadcasts.remove(userId);
5181        }
5182
5183        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5184        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5185                userId, providers)) {
5186            if (!doit) {
5187                return true;
5188            }
5189            didSomething = true;
5190        }
5191        N = providers.size();
5192        for (i=0; i<N; i++) {
5193            removeDyingProviderLocked(null, providers.get(i), true);
5194        }
5195
5196        // Remove transient permissions granted from/to this package/user
5197        removeUriPermissionsForPackageLocked(name, userId, false);
5198
5199        if (name == null || uninstalling) {
5200            // Remove pending intents.  For now we only do this when force
5201            // stopping users, because we have some problems when doing this
5202            // for packages -- app widgets are not currently cleaned up for
5203            // such packages, so they can be left with bad pending intents.
5204            if (mIntentSenderRecords.size() > 0) {
5205                Iterator<WeakReference<PendingIntentRecord>> it
5206                        = mIntentSenderRecords.values().iterator();
5207                while (it.hasNext()) {
5208                    WeakReference<PendingIntentRecord> wpir = it.next();
5209                    if (wpir == null) {
5210                        it.remove();
5211                        continue;
5212                    }
5213                    PendingIntentRecord pir = wpir.get();
5214                    if (pir == null) {
5215                        it.remove();
5216                        continue;
5217                    }
5218                    if (name == null) {
5219                        // Stopping user, remove all objects for the user.
5220                        if (pir.key.userId != userId) {
5221                            // Not the same user, skip it.
5222                            continue;
5223                        }
5224                    } else {
5225                        if (UserHandle.getAppId(pir.uid) != appId) {
5226                            // Different app id, skip it.
5227                            continue;
5228                        }
5229                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5230                            // Different user, skip it.
5231                            continue;
5232                        }
5233                        if (!pir.key.packageName.equals(name)) {
5234                            // Different package, skip it.
5235                            continue;
5236                        }
5237                    }
5238                    if (!doit) {
5239                        return true;
5240                    }
5241                    didSomething = true;
5242                    it.remove();
5243                    pir.canceled = true;
5244                    if (pir.key.activity != null) {
5245                        pir.key.activity.pendingResults.remove(pir.ref);
5246                    }
5247                }
5248            }
5249        }
5250
5251        if (doit) {
5252            if (purgeCache && name != null) {
5253                AttributeCache ac = AttributeCache.instance();
5254                if (ac != null) {
5255                    ac.removePackage(name);
5256                }
5257            }
5258            if (mBooted) {
5259                mStackSupervisor.resumeTopActivitiesLocked();
5260                mStackSupervisor.scheduleIdleLocked();
5261            }
5262        }
5263
5264        return didSomething;
5265    }
5266
5267    private final boolean removeProcessLocked(ProcessRecord app,
5268            boolean callerWillRestart, boolean allowRestart, String reason) {
5269        final String name = app.processName;
5270        final int uid = app.uid;
5271        if (DEBUG_PROCESSES) Slog.d(
5272            TAG, "Force removing proc " + app.toShortString() + " (" + name
5273            + "/" + uid + ")");
5274
5275        mProcessNames.remove(name, uid);
5276        mIsolatedProcesses.remove(app.uid);
5277        if (mHeavyWeightProcess == app) {
5278            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5279                    mHeavyWeightProcess.userId, 0));
5280            mHeavyWeightProcess = null;
5281        }
5282        boolean needRestart = false;
5283        if (app.pid > 0 && app.pid != MY_PID) {
5284            int pid = app.pid;
5285            synchronized (mPidsSelfLocked) {
5286                mPidsSelfLocked.remove(pid);
5287                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5288            }
5289            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5290            if (app.isolated) {
5291                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5292            }
5293            killUnneededProcessLocked(app, reason);
5294            Process.killProcessGroup(app.info.uid, app.pid);
5295            handleAppDiedLocked(app, true, allowRestart);
5296            removeLruProcessLocked(app);
5297
5298            if (app.persistent && !app.isolated) {
5299                if (!callerWillRestart) {
5300                    addAppLocked(app.info, false, null /* ABI override */);
5301                } else {
5302                    needRestart = true;
5303                }
5304            }
5305        } else {
5306            mRemovedProcesses.add(app);
5307        }
5308
5309        return needRestart;
5310    }
5311
5312    private final void processStartTimedOutLocked(ProcessRecord app) {
5313        final int pid = app.pid;
5314        boolean gone = false;
5315        synchronized (mPidsSelfLocked) {
5316            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5317            if (knownApp != null && knownApp.thread == null) {
5318                mPidsSelfLocked.remove(pid);
5319                gone = true;
5320            }
5321        }
5322
5323        if (gone) {
5324            Slog.w(TAG, "Process " + app + " failed to attach");
5325            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5326                    pid, app.uid, app.processName);
5327            mProcessNames.remove(app.processName, app.uid);
5328            mIsolatedProcesses.remove(app.uid);
5329            if (mHeavyWeightProcess == app) {
5330                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5331                        mHeavyWeightProcess.userId, 0));
5332                mHeavyWeightProcess = null;
5333            }
5334            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5335            if (app.isolated) {
5336                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5337            }
5338            // Take care of any launching providers waiting for this process.
5339            checkAppInLaunchingProvidersLocked(app, true);
5340            // Take care of any services that are waiting for the process.
5341            mServices.processStartTimedOutLocked(app);
5342            killUnneededProcessLocked(app, "start timeout");
5343            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5344                Slog.w(TAG, "Unattached app died before backup, skipping");
5345                try {
5346                    IBackupManager bm = IBackupManager.Stub.asInterface(
5347                            ServiceManager.getService(Context.BACKUP_SERVICE));
5348                    bm.agentDisconnected(app.info.packageName);
5349                } catch (RemoteException e) {
5350                    // Can't happen; the backup manager is local
5351                }
5352            }
5353            if (isPendingBroadcastProcessLocked(pid)) {
5354                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5355                skipPendingBroadcastLocked(pid);
5356            }
5357        } else {
5358            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5359        }
5360    }
5361
5362    private final boolean attachApplicationLocked(IApplicationThread thread,
5363            int pid) {
5364
5365        // Find the application record that is being attached...  either via
5366        // the pid if we are running in multiple processes, or just pull the
5367        // next app record if we are emulating process with anonymous threads.
5368        ProcessRecord app;
5369        if (pid != MY_PID && pid >= 0) {
5370            synchronized (mPidsSelfLocked) {
5371                app = mPidsSelfLocked.get(pid);
5372            }
5373        } else {
5374            app = null;
5375        }
5376
5377        if (app == null) {
5378            Slog.w(TAG, "No pending application record for pid " + pid
5379                    + " (IApplicationThread " + thread + "); dropping process");
5380            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5381            if (pid > 0 && pid != MY_PID) {
5382                Process.killProcessQuiet(pid);
5383                //TODO: Process.killProcessGroup(app.info.uid, pid);
5384            } else {
5385                try {
5386                    thread.scheduleExit();
5387                } catch (Exception e) {
5388                    // Ignore exceptions.
5389                }
5390            }
5391            return false;
5392        }
5393
5394        // If this application record is still attached to a previous
5395        // process, clean it up now.
5396        if (app.thread != null) {
5397            handleAppDiedLocked(app, true, true);
5398        }
5399
5400        // Tell the process all about itself.
5401
5402        if (localLOGV) Slog.v(
5403                TAG, "Binding process pid " + pid + " to record " + app);
5404
5405        final String processName = app.processName;
5406        try {
5407            AppDeathRecipient adr = new AppDeathRecipient(
5408                    app, pid, thread);
5409            thread.asBinder().linkToDeath(adr, 0);
5410            app.deathRecipient = adr;
5411        } catch (RemoteException e) {
5412            app.resetPackageList(mProcessStats);
5413            startProcessLocked(app, "link fail", processName);
5414            return false;
5415        }
5416
5417        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5418
5419        app.makeActive(thread, mProcessStats);
5420        app.curAdj = app.setAdj = -100;
5421        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5422        app.forcingToForeground = null;
5423        updateProcessForegroundLocked(app, false, false);
5424        app.hasShownUi = false;
5425        app.debugging = false;
5426        app.cached = false;
5427
5428        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5429
5430        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5431        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5432
5433        if (!normalMode) {
5434            Slog.i(TAG, "Launching preboot mode app: " + app);
5435        }
5436
5437        if (localLOGV) Slog.v(
5438            TAG, "New app record " + app
5439            + " thread=" + thread.asBinder() + " pid=" + pid);
5440        try {
5441            int testMode = IApplicationThread.DEBUG_OFF;
5442            if (mDebugApp != null && mDebugApp.equals(processName)) {
5443                testMode = mWaitForDebugger
5444                    ? IApplicationThread.DEBUG_WAIT
5445                    : IApplicationThread.DEBUG_ON;
5446                app.debugging = true;
5447                if (mDebugTransient) {
5448                    mDebugApp = mOrigDebugApp;
5449                    mWaitForDebugger = mOrigWaitForDebugger;
5450                }
5451            }
5452            String profileFile = app.instrumentationProfileFile;
5453            ParcelFileDescriptor profileFd = null;
5454            boolean profileAutoStop = false;
5455            if (mProfileApp != null && mProfileApp.equals(processName)) {
5456                mProfileProc = app;
5457                profileFile = mProfileFile;
5458                profileFd = mProfileFd;
5459                profileAutoStop = mAutoStopProfiler;
5460            }
5461            boolean enableOpenGlTrace = false;
5462            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5463                enableOpenGlTrace = true;
5464                mOpenGlTraceApp = null;
5465            }
5466
5467            // If the app is being launched for restore or full backup, set it up specially
5468            boolean isRestrictedBackupMode = false;
5469            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5470                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5471                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5472                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5473            }
5474
5475            ensurePackageDexOpt(app.instrumentationInfo != null
5476                    ? app.instrumentationInfo.packageName
5477                    : app.info.packageName);
5478            if (app.instrumentationClass != null) {
5479                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5480            }
5481            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5482                    + processName + " with config " + mConfiguration);
5483            ApplicationInfo appInfo = app.instrumentationInfo != null
5484                    ? app.instrumentationInfo : app.info;
5485            app.compat = compatibilityInfoForPackageLocked(appInfo);
5486            if (profileFd != null) {
5487                profileFd = profileFd.dup();
5488            }
5489            thread.bindApplication(processName, appInfo, providers,
5490                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5491                    app.instrumentationArguments, app.instrumentationWatcher,
5492                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5493                    isRestrictedBackupMode || !normalMode, app.persistent,
5494                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5495                    mCoreSettingsObserver.getCoreSettingsLocked());
5496            updateLruProcessLocked(app, false, null);
5497            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5498        } catch (Exception e) {
5499            // todo: Yikes!  What should we do?  For now we will try to
5500            // start another process, but that could easily get us in
5501            // an infinite loop of restarting processes...
5502            Slog.w(TAG, "Exception thrown during bind!", e);
5503
5504            app.resetPackageList(mProcessStats);
5505            app.unlinkDeathRecipient();
5506            startProcessLocked(app, "bind fail", processName);
5507            return false;
5508        }
5509
5510        // Remove this record from the list of starting applications.
5511        mPersistentStartingProcesses.remove(app);
5512        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5513                "Attach application locked removing on hold: " + app);
5514        mProcessesOnHold.remove(app);
5515
5516        boolean badApp = false;
5517        boolean didSomething = false;
5518
5519        // See if the top visible activity is waiting to run in this process...
5520        if (normalMode) {
5521            try {
5522                if (mStackSupervisor.attachApplicationLocked(app)) {
5523                    didSomething = true;
5524                }
5525            } catch (Exception e) {
5526                badApp = true;
5527            }
5528        }
5529
5530        // Find any services that should be running in this process...
5531        if (!badApp) {
5532            try {
5533                didSomething |= mServices.attachApplicationLocked(app, processName);
5534            } catch (Exception e) {
5535                badApp = true;
5536            }
5537        }
5538
5539        // Check if a next-broadcast receiver is in this process...
5540        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5541            try {
5542                didSomething |= sendPendingBroadcastsLocked(app);
5543            } catch (Exception e) {
5544                // If the app died trying to launch the receiver we declare it 'bad'
5545                badApp = true;
5546            }
5547        }
5548
5549        // Check whether the next backup agent is in this process...
5550        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5551            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5552            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5553            try {
5554                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5555                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5556                        mBackupTarget.backupMode);
5557            } catch (Exception e) {
5558                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5559                e.printStackTrace();
5560            }
5561        }
5562
5563        if (badApp) {
5564            // todo: Also need to kill application to deal with all
5565            // kinds of exceptions.
5566            handleAppDiedLocked(app, false, true);
5567            return false;
5568        }
5569
5570        if (!didSomething) {
5571            updateOomAdjLocked();
5572        }
5573
5574        return true;
5575    }
5576
5577    @Override
5578    public final void attachApplication(IApplicationThread thread) {
5579        synchronized (this) {
5580            int callingPid = Binder.getCallingPid();
5581            final long origId = Binder.clearCallingIdentity();
5582            attachApplicationLocked(thread, callingPid);
5583            Binder.restoreCallingIdentity(origId);
5584        }
5585    }
5586
5587    @Override
5588    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5589        final long origId = Binder.clearCallingIdentity();
5590        synchronized (this) {
5591            ActivityStack stack = ActivityRecord.getStackLocked(token);
5592            if (stack != null) {
5593                ActivityRecord r =
5594                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5595                if (stopProfiling) {
5596                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5597                        try {
5598                            mProfileFd.close();
5599                        } catch (IOException e) {
5600                        }
5601                        clearProfilerLocked();
5602                    }
5603                }
5604            }
5605        }
5606        Binder.restoreCallingIdentity(origId);
5607    }
5608
5609    void postEnableScreenAfterBootLocked() {
5610        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5611    }
5612
5613    void enableScreenAfterBoot() {
5614        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5615                SystemClock.uptimeMillis());
5616        mWindowManager.enableScreenAfterBoot();
5617
5618        synchronized (this) {
5619            updateEventDispatchingLocked();
5620        }
5621    }
5622
5623    @Override
5624    public void showBootMessage(final CharSequence msg, final boolean always) {
5625        enforceNotIsolatedCaller("showBootMessage");
5626        mWindowManager.showBootMessage(msg, always);
5627    }
5628
5629    @Override
5630    public void dismissKeyguardOnNextActivity() {
5631        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5632        final long token = Binder.clearCallingIdentity();
5633        try {
5634            synchronized (this) {
5635                if (DEBUG_LOCKSCREEN) logLockScreen("");
5636                if (mLockScreenShown) {
5637                    mLockScreenShown = false;
5638                    comeOutOfSleepIfNeededLocked();
5639                }
5640                mStackSupervisor.setDismissKeyguard(true);
5641            }
5642        } finally {
5643            Binder.restoreCallingIdentity(token);
5644        }
5645    }
5646
5647    final void finishBooting() {
5648        // Register receivers to handle package update events
5649        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5650
5651        synchronized (this) {
5652            // Ensure that any processes we had put on hold are now started
5653            // up.
5654            final int NP = mProcessesOnHold.size();
5655            if (NP > 0) {
5656                ArrayList<ProcessRecord> procs =
5657                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5658                for (int ip=0; ip<NP; ip++) {
5659                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5660                            + procs.get(ip));
5661                    startProcessLocked(procs.get(ip), "on-hold", null);
5662                }
5663            }
5664
5665            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5666                // Start looking for apps that are abusing wake locks.
5667                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5668                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5669                // Tell anyone interested that we are done booting!
5670                SystemProperties.set("sys.boot_completed", "1");
5671                SystemProperties.set("dev.bootcomplete", "1");
5672                for (int i=0; i<mStartedUsers.size(); i++) {
5673                    UserStartedState uss = mStartedUsers.valueAt(i);
5674                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5675                        uss.mState = UserStartedState.STATE_RUNNING;
5676                        final int userId = mStartedUsers.keyAt(i);
5677                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5678                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5679                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5680                        broadcastIntentLocked(null, null, intent, null,
5681                                new IIntentReceiver.Stub() {
5682                                    @Override
5683                                    public void performReceive(Intent intent, int resultCode,
5684                                            String data, Bundle extras, boolean ordered,
5685                                            boolean sticky, int sendingUser) {
5686                                        synchronized (ActivityManagerService.this) {
5687                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5688                                                    true, false);
5689                                        }
5690                                    }
5691                                },
5692                                0, null, null,
5693                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5694                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5695                                userId);
5696                    }
5697                }
5698                scheduleStartProfilesLocked();
5699            }
5700        }
5701    }
5702
5703    final void ensureBootCompleted() {
5704        boolean booting;
5705        boolean enableScreen;
5706        synchronized (this) {
5707            booting = mBooting;
5708            mBooting = false;
5709            enableScreen = !mBooted;
5710            mBooted = true;
5711        }
5712
5713        if (booting) {
5714            finishBooting();
5715        }
5716
5717        if (enableScreen) {
5718            enableScreenAfterBoot();
5719        }
5720    }
5721
5722    @Override
5723    public final void activityResumed(IBinder token) {
5724        final long origId = Binder.clearCallingIdentity();
5725        synchronized(this) {
5726            ActivityStack stack = ActivityRecord.getStackLocked(token);
5727            if (stack != null) {
5728                ActivityRecord.activityResumedLocked(token);
5729            }
5730        }
5731        Binder.restoreCallingIdentity(origId);
5732    }
5733
5734    @Override
5735    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5736        final long origId = Binder.clearCallingIdentity();
5737        synchronized(this) {
5738            ActivityStack stack = ActivityRecord.getStackLocked(token);
5739            if (stack != null) {
5740                stack.activityPausedLocked(token, false, persistentState);
5741            }
5742        }
5743        Binder.restoreCallingIdentity(origId);
5744    }
5745
5746    @Override
5747    public final void activityStopped(IBinder token, Bundle icicle,
5748            PersistableBundle persistentState, CharSequence description) {
5749        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5750
5751        // Refuse possible leaked file descriptors
5752        if (icicle != null && icicle.hasFileDescriptors()) {
5753            throw new IllegalArgumentException("File descriptors passed in Bundle");
5754        }
5755
5756        final long origId = Binder.clearCallingIdentity();
5757
5758        synchronized (this) {
5759            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5760            if (r != null) {
5761                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5762            }
5763        }
5764
5765        trimApplications();
5766
5767        Binder.restoreCallingIdentity(origId);
5768    }
5769
5770    @Override
5771    public final void activityDestroyed(IBinder token) {
5772        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5773        synchronized (this) {
5774            ActivityStack stack = ActivityRecord.getStackLocked(token);
5775            if (stack != null) {
5776                stack.activityDestroyedLocked(token);
5777            }
5778        }
5779    }
5780
5781    @Override
5782    public final void mediaResourcesReleased(IBinder token) {
5783        final long origId = Binder.clearCallingIdentity();
5784        try {
5785            synchronized (this) {
5786                ActivityStack stack = ActivityRecord.getStackLocked(token);
5787                if (stack != null) {
5788                    stack.mediaResourcesReleased(token);
5789                }
5790            }
5791        } finally {
5792            Binder.restoreCallingIdentity(origId);
5793        }
5794    }
5795
5796    @Override
5797    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5798        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5799    }
5800
5801    @Override
5802    public final void notifyEnterAnimationComplete(IBinder token) {
5803        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5804    }
5805
5806    @Override
5807    public String getCallingPackage(IBinder token) {
5808        synchronized (this) {
5809            ActivityRecord r = getCallingRecordLocked(token);
5810            return r != null ? r.info.packageName : null;
5811        }
5812    }
5813
5814    @Override
5815    public ComponentName getCallingActivity(IBinder token) {
5816        synchronized (this) {
5817            ActivityRecord r = getCallingRecordLocked(token);
5818            return r != null ? r.intent.getComponent() : null;
5819        }
5820    }
5821
5822    private ActivityRecord getCallingRecordLocked(IBinder token) {
5823        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5824        if (r == null) {
5825            return null;
5826        }
5827        return r.resultTo;
5828    }
5829
5830    @Override
5831    public ComponentName getActivityClassForToken(IBinder token) {
5832        synchronized(this) {
5833            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5834            if (r == null) {
5835                return null;
5836            }
5837            return r.intent.getComponent();
5838        }
5839    }
5840
5841    @Override
5842    public String getPackageForToken(IBinder token) {
5843        synchronized(this) {
5844            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5845            if (r == null) {
5846                return null;
5847            }
5848            return r.packageName;
5849        }
5850    }
5851
5852    @Override
5853    public IIntentSender getIntentSender(int type,
5854            String packageName, IBinder token, String resultWho,
5855            int requestCode, Intent[] intents, String[] resolvedTypes,
5856            int flags, Bundle options, int userId) {
5857        enforceNotIsolatedCaller("getIntentSender");
5858        // Refuse possible leaked file descriptors
5859        if (intents != null) {
5860            if (intents.length < 1) {
5861                throw new IllegalArgumentException("Intents array length must be >= 1");
5862            }
5863            for (int i=0; i<intents.length; i++) {
5864                Intent intent = intents[i];
5865                if (intent != null) {
5866                    if (intent.hasFileDescriptors()) {
5867                        throw new IllegalArgumentException("File descriptors passed in Intent");
5868                    }
5869                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5870                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5871                        throw new IllegalArgumentException(
5872                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5873                    }
5874                    intents[i] = new Intent(intent);
5875                }
5876            }
5877            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5878                throw new IllegalArgumentException(
5879                        "Intent array length does not match resolvedTypes length");
5880            }
5881        }
5882        if (options != null) {
5883            if (options.hasFileDescriptors()) {
5884                throw new IllegalArgumentException("File descriptors passed in options");
5885            }
5886        }
5887
5888        synchronized(this) {
5889            int callingUid = Binder.getCallingUid();
5890            int origUserId = userId;
5891            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5892                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5893                    ALLOW_NON_FULL, "getIntentSender", null);
5894            if (origUserId == UserHandle.USER_CURRENT) {
5895                // We don't want to evaluate this until the pending intent is
5896                // actually executed.  However, we do want to always do the
5897                // security checking for it above.
5898                userId = UserHandle.USER_CURRENT;
5899            }
5900            try {
5901                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5902                    int uid = AppGlobals.getPackageManager()
5903                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5904                    if (!UserHandle.isSameApp(callingUid, uid)) {
5905                        String msg = "Permission Denial: getIntentSender() from pid="
5906                            + Binder.getCallingPid()
5907                            + ", uid=" + Binder.getCallingUid()
5908                            + ", (need uid=" + uid + ")"
5909                            + " is not allowed to send as package " + packageName;
5910                        Slog.w(TAG, msg);
5911                        throw new SecurityException(msg);
5912                    }
5913                }
5914
5915                return getIntentSenderLocked(type, packageName, callingUid, userId,
5916                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5917
5918            } catch (RemoteException e) {
5919                throw new SecurityException(e);
5920            }
5921        }
5922    }
5923
5924    IIntentSender getIntentSenderLocked(int type, String packageName,
5925            int callingUid, int userId, IBinder token, String resultWho,
5926            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5927            Bundle options) {
5928        if (DEBUG_MU)
5929            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5930        ActivityRecord activity = null;
5931        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5932            activity = ActivityRecord.isInStackLocked(token);
5933            if (activity == null) {
5934                return null;
5935            }
5936            if (activity.finishing) {
5937                return null;
5938            }
5939        }
5940
5941        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5942        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5943        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5944        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5945                |PendingIntent.FLAG_UPDATE_CURRENT);
5946
5947        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5948                type, packageName, activity, resultWho,
5949                requestCode, intents, resolvedTypes, flags, options, userId);
5950        WeakReference<PendingIntentRecord> ref;
5951        ref = mIntentSenderRecords.get(key);
5952        PendingIntentRecord rec = ref != null ? ref.get() : null;
5953        if (rec != null) {
5954            if (!cancelCurrent) {
5955                if (updateCurrent) {
5956                    if (rec.key.requestIntent != null) {
5957                        rec.key.requestIntent.replaceExtras(intents != null ?
5958                                intents[intents.length - 1] : null);
5959                    }
5960                    if (intents != null) {
5961                        intents[intents.length-1] = rec.key.requestIntent;
5962                        rec.key.allIntents = intents;
5963                        rec.key.allResolvedTypes = resolvedTypes;
5964                    } else {
5965                        rec.key.allIntents = null;
5966                        rec.key.allResolvedTypes = null;
5967                    }
5968                }
5969                return rec;
5970            }
5971            rec.canceled = true;
5972            mIntentSenderRecords.remove(key);
5973        }
5974        if (noCreate) {
5975            return rec;
5976        }
5977        rec = new PendingIntentRecord(this, key, callingUid);
5978        mIntentSenderRecords.put(key, rec.ref);
5979        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5980            if (activity.pendingResults == null) {
5981                activity.pendingResults
5982                        = new HashSet<WeakReference<PendingIntentRecord>>();
5983            }
5984            activity.pendingResults.add(rec.ref);
5985        }
5986        return rec;
5987    }
5988
5989    @Override
5990    public void cancelIntentSender(IIntentSender sender) {
5991        if (!(sender instanceof PendingIntentRecord)) {
5992            return;
5993        }
5994        synchronized(this) {
5995            PendingIntentRecord rec = (PendingIntentRecord)sender;
5996            try {
5997                int uid = AppGlobals.getPackageManager()
5998                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5999                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6000                    String msg = "Permission Denial: cancelIntentSender() from pid="
6001                        + Binder.getCallingPid()
6002                        + ", uid=" + Binder.getCallingUid()
6003                        + " is not allowed to cancel packges "
6004                        + rec.key.packageName;
6005                    Slog.w(TAG, msg);
6006                    throw new SecurityException(msg);
6007                }
6008            } catch (RemoteException e) {
6009                throw new SecurityException(e);
6010            }
6011            cancelIntentSenderLocked(rec, true);
6012        }
6013    }
6014
6015    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6016        rec.canceled = true;
6017        mIntentSenderRecords.remove(rec.key);
6018        if (cleanActivity && rec.key.activity != null) {
6019            rec.key.activity.pendingResults.remove(rec.ref);
6020        }
6021    }
6022
6023    @Override
6024    public String getPackageForIntentSender(IIntentSender pendingResult) {
6025        if (!(pendingResult instanceof PendingIntentRecord)) {
6026            return null;
6027        }
6028        try {
6029            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6030            return res.key.packageName;
6031        } catch (ClassCastException e) {
6032        }
6033        return null;
6034    }
6035
6036    @Override
6037    public int getUidForIntentSender(IIntentSender sender) {
6038        if (sender instanceof PendingIntentRecord) {
6039            try {
6040                PendingIntentRecord res = (PendingIntentRecord)sender;
6041                return res.uid;
6042            } catch (ClassCastException e) {
6043            }
6044        }
6045        return -1;
6046    }
6047
6048    @Override
6049    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6050        if (!(pendingResult instanceof PendingIntentRecord)) {
6051            return false;
6052        }
6053        try {
6054            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6055            if (res.key.allIntents == null) {
6056                return false;
6057            }
6058            for (int i=0; i<res.key.allIntents.length; i++) {
6059                Intent intent = res.key.allIntents[i];
6060                if (intent.getPackage() != null && intent.getComponent() != null) {
6061                    return false;
6062                }
6063            }
6064            return true;
6065        } catch (ClassCastException e) {
6066        }
6067        return false;
6068    }
6069
6070    @Override
6071    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6072        if (!(pendingResult instanceof PendingIntentRecord)) {
6073            return false;
6074        }
6075        try {
6076            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6077            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6078                return true;
6079            }
6080            return false;
6081        } catch (ClassCastException e) {
6082        }
6083        return false;
6084    }
6085
6086    @Override
6087    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6088        if (!(pendingResult instanceof PendingIntentRecord)) {
6089            return null;
6090        }
6091        try {
6092            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6093            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6094        } catch (ClassCastException e) {
6095        }
6096        return null;
6097    }
6098
6099    @Override
6100    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6101        if (!(pendingResult instanceof PendingIntentRecord)) {
6102            return null;
6103        }
6104        try {
6105            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6106            Intent intent = res.key.requestIntent;
6107            if (intent != null) {
6108                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6109                        || res.lastTagPrefix.equals(prefix))) {
6110                    return res.lastTag;
6111                }
6112                res.lastTagPrefix = prefix;
6113                StringBuilder sb = new StringBuilder(128);
6114                if (prefix != null) {
6115                    sb.append(prefix);
6116                }
6117                if (intent.getAction() != null) {
6118                    sb.append(intent.getAction());
6119                } else if (intent.getComponent() != null) {
6120                    intent.getComponent().appendShortString(sb);
6121                } else {
6122                    sb.append("?");
6123                }
6124                return res.lastTag = sb.toString();
6125            }
6126        } catch (ClassCastException e) {
6127        }
6128        return null;
6129    }
6130
6131    @Override
6132    public void setProcessLimit(int max) {
6133        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6134                "setProcessLimit()");
6135        synchronized (this) {
6136            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6137            mProcessLimitOverride = max;
6138        }
6139        trimApplications();
6140    }
6141
6142    @Override
6143    public int getProcessLimit() {
6144        synchronized (this) {
6145            return mProcessLimitOverride;
6146        }
6147    }
6148
6149    void foregroundTokenDied(ForegroundToken token) {
6150        synchronized (ActivityManagerService.this) {
6151            synchronized (mPidsSelfLocked) {
6152                ForegroundToken cur
6153                    = mForegroundProcesses.get(token.pid);
6154                if (cur != token) {
6155                    return;
6156                }
6157                mForegroundProcesses.remove(token.pid);
6158                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6159                if (pr == null) {
6160                    return;
6161                }
6162                pr.forcingToForeground = null;
6163                updateProcessForegroundLocked(pr, false, false);
6164            }
6165            updateOomAdjLocked();
6166        }
6167    }
6168
6169    @Override
6170    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6171        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6172                "setProcessForeground()");
6173        synchronized(this) {
6174            boolean changed = false;
6175
6176            synchronized (mPidsSelfLocked) {
6177                ProcessRecord pr = mPidsSelfLocked.get(pid);
6178                if (pr == null && isForeground) {
6179                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6180                    return;
6181                }
6182                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6183                if (oldToken != null) {
6184                    oldToken.token.unlinkToDeath(oldToken, 0);
6185                    mForegroundProcesses.remove(pid);
6186                    if (pr != null) {
6187                        pr.forcingToForeground = null;
6188                    }
6189                    changed = true;
6190                }
6191                if (isForeground && token != null) {
6192                    ForegroundToken newToken = new ForegroundToken() {
6193                        @Override
6194                        public void binderDied() {
6195                            foregroundTokenDied(this);
6196                        }
6197                    };
6198                    newToken.pid = pid;
6199                    newToken.token = token;
6200                    try {
6201                        token.linkToDeath(newToken, 0);
6202                        mForegroundProcesses.put(pid, newToken);
6203                        pr.forcingToForeground = token;
6204                        changed = true;
6205                    } catch (RemoteException e) {
6206                        // If the process died while doing this, we will later
6207                        // do the cleanup with the process death link.
6208                    }
6209                }
6210            }
6211
6212            if (changed) {
6213                updateOomAdjLocked();
6214            }
6215        }
6216    }
6217
6218    // =========================================================
6219    // PERMISSIONS
6220    // =========================================================
6221
6222    static class PermissionController extends IPermissionController.Stub {
6223        ActivityManagerService mActivityManagerService;
6224        PermissionController(ActivityManagerService activityManagerService) {
6225            mActivityManagerService = activityManagerService;
6226        }
6227
6228        @Override
6229        public boolean checkPermission(String permission, int pid, int uid) {
6230            return mActivityManagerService.checkPermission(permission, pid,
6231                    uid) == PackageManager.PERMISSION_GRANTED;
6232        }
6233    }
6234
6235    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6236        @Override
6237        public int checkComponentPermission(String permission, int pid, int uid,
6238                int owningUid, boolean exported) {
6239            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6240                    owningUid, exported);
6241        }
6242
6243        @Override
6244        public Object getAMSLock() {
6245            return ActivityManagerService.this;
6246        }
6247    }
6248
6249    /**
6250     * This can be called with or without the global lock held.
6251     */
6252    int checkComponentPermission(String permission, int pid, int uid,
6253            int owningUid, boolean exported) {
6254        // We might be performing an operation on behalf of an indirect binder
6255        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6256        // client identity accordingly before proceeding.
6257        Identity tlsIdentity = sCallerIdentity.get();
6258        if (tlsIdentity != null) {
6259            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6260                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6261            uid = tlsIdentity.uid;
6262            pid = tlsIdentity.pid;
6263        }
6264
6265        if (pid == MY_PID) {
6266            return PackageManager.PERMISSION_GRANTED;
6267        }
6268
6269        return ActivityManager.checkComponentPermission(permission, uid,
6270                owningUid, exported);
6271    }
6272
6273    /**
6274     * As the only public entry point for permissions checking, this method
6275     * can enforce the semantic that requesting a check on a null global
6276     * permission is automatically denied.  (Internally a null permission
6277     * string is used when calling {@link #checkComponentPermission} in cases
6278     * when only uid-based security is needed.)
6279     *
6280     * This can be called with or without the global lock held.
6281     */
6282    @Override
6283    public int checkPermission(String permission, int pid, int uid) {
6284        if (permission == null) {
6285            return PackageManager.PERMISSION_DENIED;
6286        }
6287        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6288    }
6289
6290    /**
6291     * Binder IPC calls go through the public entry point.
6292     * This can be called with or without the global lock held.
6293     */
6294    int checkCallingPermission(String permission) {
6295        return checkPermission(permission,
6296                Binder.getCallingPid(),
6297                UserHandle.getAppId(Binder.getCallingUid()));
6298    }
6299
6300    /**
6301     * This can be called with or without the global lock held.
6302     */
6303    void enforceCallingPermission(String permission, String func) {
6304        if (checkCallingPermission(permission)
6305                == PackageManager.PERMISSION_GRANTED) {
6306            return;
6307        }
6308
6309        String msg = "Permission Denial: " + func + " from pid="
6310                + Binder.getCallingPid()
6311                + ", uid=" + Binder.getCallingUid()
6312                + " requires " + permission;
6313        Slog.w(TAG, msg);
6314        throw new SecurityException(msg);
6315    }
6316
6317    /**
6318     * Determine if UID is holding permissions required to access {@link Uri} in
6319     * the given {@link ProviderInfo}. Final permission checking is always done
6320     * in {@link ContentProvider}.
6321     */
6322    private final boolean checkHoldingPermissionsLocked(
6323            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6324        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6325                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6326        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6327            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6328                    != PERMISSION_GRANTED) {
6329                return false;
6330            }
6331        }
6332        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6333    }
6334
6335    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6336            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6337        if (pi.applicationInfo.uid == uid) {
6338            return true;
6339        } else if (!pi.exported) {
6340            return false;
6341        }
6342
6343        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6344        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6345        try {
6346            // check if target holds top-level <provider> permissions
6347            if (!readMet && pi.readPermission != null && considerUidPermissions
6348                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6349                readMet = true;
6350            }
6351            if (!writeMet && pi.writePermission != null && considerUidPermissions
6352                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6353                writeMet = true;
6354            }
6355
6356            // track if unprotected read/write is allowed; any denied
6357            // <path-permission> below removes this ability
6358            boolean allowDefaultRead = pi.readPermission == null;
6359            boolean allowDefaultWrite = pi.writePermission == null;
6360
6361            // check if target holds any <path-permission> that match uri
6362            final PathPermission[] pps = pi.pathPermissions;
6363            if (pps != null) {
6364                final String path = grantUri.uri.getPath();
6365                int i = pps.length;
6366                while (i > 0 && (!readMet || !writeMet)) {
6367                    i--;
6368                    PathPermission pp = pps[i];
6369                    if (pp.match(path)) {
6370                        if (!readMet) {
6371                            final String pprperm = pp.getReadPermission();
6372                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6373                                    + pprperm + " for " + pp.getPath()
6374                                    + ": match=" + pp.match(path)
6375                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6376                            if (pprperm != null) {
6377                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6378                                        == PERMISSION_GRANTED) {
6379                                    readMet = true;
6380                                } else {
6381                                    allowDefaultRead = false;
6382                                }
6383                            }
6384                        }
6385                        if (!writeMet) {
6386                            final String ppwperm = pp.getWritePermission();
6387                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6388                                    + ppwperm + " for " + pp.getPath()
6389                                    + ": match=" + pp.match(path)
6390                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6391                            if (ppwperm != null) {
6392                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6393                                        == PERMISSION_GRANTED) {
6394                                    writeMet = true;
6395                                } else {
6396                                    allowDefaultWrite = false;
6397                                }
6398                            }
6399                        }
6400                    }
6401                }
6402            }
6403
6404            // grant unprotected <provider> read/write, if not blocked by
6405            // <path-permission> above
6406            if (allowDefaultRead) readMet = true;
6407            if (allowDefaultWrite) writeMet = true;
6408
6409        } catch (RemoteException e) {
6410            return false;
6411        }
6412
6413        return readMet && writeMet;
6414    }
6415
6416    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6417        ProviderInfo pi = null;
6418        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6419        if (cpr != null) {
6420            pi = cpr.info;
6421        } else {
6422            try {
6423                pi = AppGlobals.getPackageManager().resolveContentProvider(
6424                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6425            } catch (RemoteException ex) {
6426            }
6427        }
6428        return pi;
6429    }
6430
6431    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6432        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6433        if (targetUris != null) {
6434            return targetUris.get(grantUri);
6435        }
6436        return null;
6437    }
6438
6439    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6440            String targetPkg, int targetUid, GrantUri grantUri) {
6441        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6442        if (targetUris == null) {
6443            targetUris = Maps.newArrayMap();
6444            mGrantedUriPermissions.put(targetUid, targetUris);
6445        }
6446
6447        UriPermission perm = targetUris.get(grantUri);
6448        if (perm == null) {
6449            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6450            targetUris.put(grantUri, perm);
6451        }
6452
6453        return perm;
6454    }
6455
6456    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6457            final int modeFlags) {
6458        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6459        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6460                : UriPermission.STRENGTH_OWNED;
6461
6462        // Root gets to do everything.
6463        if (uid == 0) {
6464            return true;
6465        }
6466
6467        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6468        if (perms == null) return false;
6469
6470        // First look for exact match
6471        final UriPermission exactPerm = perms.get(grantUri);
6472        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6473            return true;
6474        }
6475
6476        // No exact match, look for prefixes
6477        final int N = perms.size();
6478        for (int i = 0; i < N; i++) {
6479            final UriPermission perm = perms.valueAt(i);
6480            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6481                    && perm.getStrength(modeFlags) >= minStrength) {
6482                return true;
6483            }
6484        }
6485
6486        return false;
6487    }
6488
6489    @Override
6490    public int checkUriPermission(Uri uri, int pid, int uid,
6491            final int modeFlags, int userId) {
6492        enforceNotIsolatedCaller("checkUriPermission");
6493
6494        // Another redirected-binder-call permissions check as in
6495        // {@link checkComponentPermission}.
6496        Identity tlsIdentity = sCallerIdentity.get();
6497        if (tlsIdentity != null) {
6498            uid = tlsIdentity.uid;
6499            pid = tlsIdentity.pid;
6500        }
6501
6502        // Our own process gets to do everything.
6503        if (pid == MY_PID) {
6504            return PackageManager.PERMISSION_GRANTED;
6505        }
6506        synchronized (this) {
6507            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6508                    ? PackageManager.PERMISSION_GRANTED
6509                    : PackageManager.PERMISSION_DENIED;
6510        }
6511    }
6512
6513    /**
6514     * Check if the targetPkg can be granted permission to access uri by
6515     * the callingUid using the given modeFlags.  Throws a security exception
6516     * if callingUid is not allowed to do this.  Returns the uid of the target
6517     * if the URI permission grant should be performed; returns -1 if it is not
6518     * needed (for example targetPkg already has permission to access the URI).
6519     * If you already know the uid of the target, you can supply it in
6520     * lastTargetUid else set that to -1.
6521     */
6522    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6523            final int modeFlags, int lastTargetUid) {
6524        if (!Intent.isAccessUriMode(modeFlags)) {
6525            return -1;
6526        }
6527
6528        if (targetPkg != null) {
6529            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6530                    "Checking grant " + targetPkg + " permission to " + grantUri);
6531        }
6532
6533        final IPackageManager pm = AppGlobals.getPackageManager();
6534
6535        // If this is not a content: uri, we can't do anything with it.
6536        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6537            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6538                    "Can't grant URI permission for non-content URI: " + grantUri);
6539            return -1;
6540        }
6541
6542        final String authority = grantUri.uri.getAuthority();
6543        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6544        if (pi == null) {
6545            Slog.w(TAG, "No content provider found for permission check: " +
6546                    grantUri.uri.toSafeString());
6547            return -1;
6548        }
6549
6550        int targetUid = lastTargetUid;
6551        if (targetUid < 0 && targetPkg != null) {
6552            try {
6553                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6554                if (targetUid < 0) {
6555                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6556                            "Can't grant URI permission no uid for: " + targetPkg);
6557                    return -1;
6558                }
6559            } catch (RemoteException ex) {
6560                return -1;
6561            }
6562        }
6563
6564        if (targetUid >= 0) {
6565            // First...  does the target actually need this permission?
6566            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6567                // No need to grant the target this permission.
6568                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6569                        "Target " + targetPkg + " already has full permission to " + grantUri);
6570                return -1;
6571            }
6572        } else {
6573            // First...  there is no target package, so can anyone access it?
6574            boolean allowed = pi.exported;
6575            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6576                if (pi.readPermission != null) {
6577                    allowed = false;
6578                }
6579            }
6580            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6581                if (pi.writePermission != null) {
6582                    allowed = false;
6583                }
6584            }
6585            if (allowed) {
6586                return -1;
6587            }
6588        }
6589
6590        /* There is a special cross user grant if:
6591         * - The target is on another user.
6592         * - Apps on the current user can access the uri without any uid permissions.
6593         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6594         * grant uri permissions.
6595         */
6596        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6597                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6598                modeFlags, false /*without considering the uid permissions*/);
6599
6600        // Second...  is the provider allowing granting of URI permissions?
6601        if (!specialCrossUserGrant) {
6602            if (!pi.grantUriPermissions) {
6603                throw new SecurityException("Provider " + pi.packageName
6604                        + "/" + pi.name
6605                        + " does not allow granting of Uri permissions (uri "
6606                        + grantUri + ")");
6607            }
6608            if (pi.uriPermissionPatterns != null) {
6609                final int N = pi.uriPermissionPatterns.length;
6610                boolean allowed = false;
6611                for (int i=0; i<N; i++) {
6612                    if (pi.uriPermissionPatterns[i] != null
6613                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6614                        allowed = true;
6615                        break;
6616                    }
6617                }
6618                if (!allowed) {
6619                    throw new SecurityException("Provider " + pi.packageName
6620                            + "/" + pi.name
6621                            + " does not allow granting of permission to path of Uri "
6622                            + grantUri);
6623                }
6624            }
6625        }
6626
6627        // Third...  does the caller itself have permission to access
6628        // this uri?
6629        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6630            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6631                // Require they hold a strong enough Uri permission
6632                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6633                    throw new SecurityException("Uid " + callingUid
6634                            + " does not have permission to uri " + grantUri);
6635                }
6636            }
6637        }
6638        return targetUid;
6639    }
6640
6641    @Override
6642    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6643            final int modeFlags, int userId) {
6644        enforceNotIsolatedCaller("checkGrantUriPermission");
6645        synchronized(this) {
6646            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6647                    new GrantUri(userId, uri, false), modeFlags, -1);
6648        }
6649    }
6650
6651    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6652            final int modeFlags, UriPermissionOwner owner) {
6653        if (!Intent.isAccessUriMode(modeFlags)) {
6654            return;
6655        }
6656
6657        // So here we are: the caller has the assumed permission
6658        // to the uri, and the target doesn't.  Let's now give this to
6659        // the target.
6660
6661        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6662                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6663
6664        final String authority = grantUri.uri.getAuthority();
6665        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6666        if (pi == null) {
6667            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6668            return;
6669        }
6670
6671        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6672            grantUri.prefix = true;
6673        }
6674        final UriPermission perm = findOrCreateUriPermissionLocked(
6675                pi.packageName, targetPkg, targetUid, grantUri);
6676        perm.grantModes(modeFlags, owner);
6677    }
6678
6679    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6680            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6681        if (targetPkg == null) {
6682            throw new NullPointerException("targetPkg");
6683        }
6684        int targetUid;
6685        final IPackageManager pm = AppGlobals.getPackageManager();
6686        try {
6687            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6688        } catch (RemoteException ex) {
6689            return;
6690        }
6691
6692        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6693                targetUid);
6694        if (targetUid < 0) {
6695            return;
6696        }
6697
6698        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6699                owner);
6700    }
6701
6702    static class NeededUriGrants extends ArrayList<GrantUri> {
6703        final String targetPkg;
6704        final int targetUid;
6705        final int flags;
6706
6707        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6708            this.targetPkg = targetPkg;
6709            this.targetUid = targetUid;
6710            this.flags = flags;
6711        }
6712    }
6713
6714    /**
6715     * Like checkGrantUriPermissionLocked, but takes an Intent.
6716     */
6717    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6718            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6719        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6720                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6721                + " clip=" + (intent != null ? intent.getClipData() : null)
6722                + " from " + intent + "; flags=0x"
6723                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6724
6725        if (targetPkg == null) {
6726            throw new NullPointerException("targetPkg");
6727        }
6728
6729        if (intent == null) {
6730            return null;
6731        }
6732        Uri data = intent.getData();
6733        ClipData clip = intent.getClipData();
6734        if (data == null && clip == null) {
6735            return null;
6736        }
6737        // Default userId for uris in the intent (if they don't specify it themselves)
6738        int contentUserHint = intent.getContentUserHint();
6739        if (contentUserHint == UserHandle.USER_CURRENT) {
6740            contentUserHint = UserHandle.getUserId(callingUid);
6741        }
6742        final IPackageManager pm = AppGlobals.getPackageManager();
6743        int targetUid;
6744        if (needed != null) {
6745            targetUid = needed.targetUid;
6746        } else {
6747            try {
6748                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6749            } catch (RemoteException ex) {
6750                return null;
6751            }
6752            if (targetUid < 0) {
6753                if (DEBUG_URI_PERMISSION) {
6754                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6755                            + " on user " + targetUserId);
6756                }
6757                return null;
6758            }
6759        }
6760        if (data != null) {
6761            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6762            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6763                    targetUid);
6764            if (targetUid > 0) {
6765                if (needed == null) {
6766                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6767                }
6768                needed.add(grantUri);
6769            }
6770        }
6771        if (clip != null) {
6772            for (int i=0; i<clip.getItemCount(); i++) {
6773                Uri uri = clip.getItemAt(i).getUri();
6774                if (uri != null) {
6775                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6776                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6777                            targetUid);
6778                    if (targetUid > 0) {
6779                        if (needed == null) {
6780                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6781                        }
6782                        needed.add(grantUri);
6783                    }
6784                } else {
6785                    Intent clipIntent = clip.getItemAt(i).getIntent();
6786                    if (clipIntent != null) {
6787                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6788                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6789                        if (newNeeded != null) {
6790                            needed = newNeeded;
6791                        }
6792                    }
6793                }
6794            }
6795        }
6796
6797        return needed;
6798    }
6799
6800    /**
6801     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6802     */
6803    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6804            UriPermissionOwner owner) {
6805        if (needed != null) {
6806            for (int i=0; i<needed.size(); i++) {
6807                GrantUri grantUri = needed.get(i);
6808                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6809                        grantUri, needed.flags, owner);
6810            }
6811        }
6812    }
6813
6814    void grantUriPermissionFromIntentLocked(int callingUid,
6815            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6816        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6817                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6818        if (needed == null) {
6819            return;
6820        }
6821
6822        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6823    }
6824
6825    @Override
6826    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6827            final int modeFlags, int userId) {
6828        enforceNotIsolatedCaller("grantUriPermission");
6829        GrantUri grantUri = new GrantUri(userId, uri, false);
6830        synchronized(this) {
6831            final ProcessRecord r = getRecordForAppLocked(caller);
6832            if (r == null) {
6833                throw new SecurityException("Unable to find app for caller "
6834                        + caller
6835                        + " when granting permission to uri " + grantUri);
6836            }
6837            if (targetPkg == null) {
6838                throw new IllegalArgumentException("null target");
6839            }
6840            if (grantUri == null) {
6841                throw new IllegalArgumentException("null uri");
6842            }
6843
6844            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6845                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6846                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6847                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6848
6849            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6850                    UserHandle.getUserId(r.uid));
6851        }
6852    }
6853
6854    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6855        if (perm.modeFlags == 0) {
6856            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6857                    perm.targetUid);
6858            if (perms != null) {
6859                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6860                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6861
6862                perms.remove(perm.uri);
6863                if (perms.isEmpty()) {
6864                    mGrantedUriPermissions.remove(perm.targetUid);
6865                }
6866            }
6867        }
6868    }
6869
6870    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6871        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6872
6873        final IPackageManager pm = AppGlobals.getPackageManager();
6874        final String authority = grantUri.uri.getAuthority();
6875        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6876        if (pi == null) {
6877            Slog.w(TAG, "No content provider found for permission revoke: "
6878                    + grantUri.toSafeString());
6879            return;
6880        }
6881
6882        // Does the caller have this permission on the URI?
6883        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6884            // Right now, if you are not the original owner of the permission,
6885            // you are not allowed to revoke it.
6886            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6887                throw new SecurityException("Uid " + callingUid
6888                        + " does not have permission to uri " + grantUri);
6889            //}
6890        }
6891
6892        boolean persistChanged = false;
6893
6894        // Go through all of the permissions and remove any that match.
6895        int N = mGrantedUriPermissions.size();
6896        for (int i = 0; i < N; i++) {
6897            final int targetUid = mGrantedUriPermissions.keyAt(i);
6898            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6899
6900            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6901                final UriPermission perm = it.next();
6902                if (perm.uri.sourceUserId == grantUri.sourceUserId
6903                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6904                    if (DEBUG_URI_PERMISSION)
6905                        Slog.v(TAG,
6906                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6907                    persistChanged |= perm.revokeModes(
6908                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6909                    if (perm.modeFlags == 0) {
6910                        it.remove();
6911                    }
6912                }
6913            }
6914
6915            if (perms.isEmpty()) {
6916                mGrantedUriPermissions.remove(targetUid);
6917                N--;
6918                i--;
6919            }
6920        }
6921
6922        if (persistChanged) {
6923            schedulePersistUriGrants();
6924        }
6925    }
6926
6927    @Override
6928    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6929            int userId) {
6930        enforceNotIsolatedCaller("revokeUriPermission");
6931        synchronized(this) {
6932            final ProcessRecord r = getRecordForAppLocked(caller);
6933            if (r == null) {
6934                throw new SecurityException("Unable to find app for caller "
6935                        + caller
6936                        + " when revoking permission to uri " + uri);
6937            }
6938            if (uri == null) {
6939                Slog.w(TAG, "revokeUriPermission: null uri");
6940                return;
6941            }
6942
6943            if (!Intent.isAccessUriMode(modeFlags)) {
6944                return;
6945            }
6946
6947            final IPackageManager pm = AppGlobals.getPackageManager();
6948            final String authority = uri.getAuthority();
6949            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6950            if (pi == null) {
6951                Slog.w(TAG, "No content provider found for permission revoke: "
6952                        + uri.toSafeString());
6953                return;
6954            }
6955
6956            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6957        }
6958    }
6959
6960    /**
6961     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6962     * given package.
6963     *
6964     * @param packageName Package name to match, or {@code null} to apply to all
6965     *            packages.
6966     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6967     *            to all users.
6968     * @param persistable If persistable grants should be removed.
6969     */
6970    private void removeUriPermissionsForPackageLocked(
6971            String packageName, int userHandle, boolean persistable) {
6972        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6973            throw new IllegalArgumentException("Must narrow by either package or user");
6974        }
6975
6976        boolean persistChanged = false;
6977
6978        int N = mGrantedUriPermissions.size();
6979        for (int i = 0; i < N; i++) {
6980            final int targetUid = mGrantedUriPermissions.keyAt(i);
6981            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6982
6983            // Only inspect grants matching user
6984            if (userHandle == UserHandle.USER_ALL
6985                    || userHandle == UserHandle.getUserId(targetUid)) {
6986                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6987                    final UriPermission perm = it.next();
6988
6989                    // Only inspect grants matching package
6990                    if (packageName == null || perm.sourcePkg.equals(packageName)
6991                            || perm.targetPkg.equals(packageName)) {
6992                        persistChanged |= perm.revokeModes(
6993                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6994
6995                        // Only remove when no modes remain; any persisted grants
6996                        // will keep this alive.
6997                        if (perm.modeFlags == 0) {
6998                            it.remove();
6999                        }
7000                    }
7001                }
7002
7003                if (perms.isEmpty()) {
7004                    mGrantedUriPermissions.remove(targetUid);
7005                    N--;
7006                    i--;
7007                }
7008            }
7009        }
7010
7011        if (persistChanged) {
7012            schedulePersistUriGrants();
7013        }
7014    }
7015
7016    @Override
7017    public IBinder newUriPermissionOwner(String name) {
7018        enforceNotIsolatedCaller("newUriPermissionOwner");
7019        synchronized(this) {
7020            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7021            return owner.getExternalTokenLocked();
7022        }
7023    }
7024
7025    @Override
7026    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7027            final int modeFlags, int sourceUserId, int targetUserId) {
7028        synchronized(this) {
7029            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7030            if (owner == null) {
7031                throw new IllegalArgumentException("Unknown owner: " + token);
7032            }
7033            if (fromUid != Binder.getCallingUid()) {
7034                if (Binder.getCallingUid() != Process.myUid()) {
7035                    // Only system code can grant URI permissions on behalf
7036                    // of other users.
7037                    throw new SecurityException("nice try");
7038                }
7039            }
7040            if (targetPkg == null) {
7041                throw new IllegalArgumentException("null target");
7042            }
7043            if (uri == null) {
7044                throw new IllegalArgumentException("null uri");
7045            }
7046
7047            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7048                    modeFlags, owner, targetUserId);
7049        }
7050    }
7051
7052    @Override
7053    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7054        synchronized(this) {
7055            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7056            if (owner == null) {
7057                throw new IllegalArgumentException("Unknown owner: " + token);
7058            }
7059
7060            if (uri == null) {
7061                owner.removeUriPermissionsLocked(mode);
7062            } else {
7063                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7064            }
7065        }
7066    }
7067
7068    private void schedulePersistUriGrants() {
7069        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7070            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7071                    10 * DateUtils.SECOND_IN_MILLIS);
7072        }
7073    }
7074
7075    private void writeGrantedUriPermissions() {
7076        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7077
7078        // Snapshot permissions so we can persist without lock
7079        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7080        synchronized (this) {
7081            final int size = mGrantedUriPermissions.size();
7082            for (int i = 0; i < size; i++) {
7083                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7084                for (UriPermission perm : perms.values()) {
7085                    if (perm.persistedModeFlags != 0) {
7086                        persist.add(perm.snapshot());
7087                    }
7088                }
7089            }
7090        }
7091
7092        FileOutputStream fos = null;
7093        try {
7094            fos = mGrantFile.startWrite();
7095
7096            XmlSerializer out = new FastXmlSerializer();
7097            out.setOutput(fos, "utf-8");
7098            out.startDocument(null, true);
7099            out.startTag(null, TAG_URI_GRANTS);
7100            for (UriPermission.Snapshot perm : persist) {
7101                out.startTag(null, TAG_URI_GRANT);
7102                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7103                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7104                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7105                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7106                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7107                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7108                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7109                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7110                out.endTag(null, TAG_URI_GRANT);
7111            }
7112            out.endTag(null, TAG_URI_GRANTS);
7113            out.endDocument();
7114
7115            mGrantFile.finishWrite(fos);
7116        } catch (IOException e) {
7117            if (fos != null) {
7118                mGrantFile.failWrite(fos);
7119            }
7120        }
7121    }
7122
7123    private void readGrantedUriPermissionsLocked() {
7124        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7125
7126        final long now = System.currentTimeMillis();
7127
7128        FileInputStream fis = null;
7129        try {
7130            fis = mGrantFile.openRead();
7131            final XmlPullParser in = Xml.newPullParser();
7132            in.setInput(fis, null);
7133
7134            int type;
7135            while ((type = in.next()) != END_DOCUMENT) {
7136                final String tag = in.getName();
7137                if (type == START_TAG) {
7138                    if (TAG_URI_GRANT.equals(tag)) {
7139                        final int sourceUserId;
7140                        final int targetUserId;
7141                        final int userHandle = readIntAttribute(in,
7142                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7143                        if (userHandle != UserHandle.USER_NULL) {
7144                            // For backwards compatibility.
7145                            sourceUserId = userHandle;
7146                            targetUserId = userHandle;
7147                        } else {
7148                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7149                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7150                        }
7151                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7152                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7153                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7154                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7155                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7156                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7157
7158                        // Sanity check that provider still belongs to source package
7159                        final ProviderInfo pi = getProviderInfoLocked(
7160                                uri.getAuthority(), sourceUserId);
7161                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7162                            int targetUid = -1;
7163                            try {
7164                                targetUid = AppGlobals.getPackageManager()
7165                                        .getPackageUid(targetPkg, targetUserId);
7166                            } catch (RemoteException e) {
7167                            }
7168                            if (targetUid != -1) {
7169                                final UriPermission perm = findOrCreateUriPermissionLocked(
7170                                        sourcePkg, targetPkg, targetUid,
7171                                        new GrantUri(sourceUserId, uri, prefix));
7172                                perm.initPersistedModes(modeFlags, createdTime);
7173                            }
7174                        } else {
7175                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7176                                    + " but instead found " + pi);
7177                        }
7178                    }
7179                }
7180            }
7181        } catch (FileNotFoundException e) {
7182            // Missing grants is okay
7183        } catch (IOException e) {
7184            Log.wtf(TAG, "Failed reading Uri grants", e);
7185        } catch (XmlPullParserException e) {
7186            Log.wtf(TAG, "Failed reading Uri grants", e);
7187        } finally {
7188            IoUtils.closeQuietly(fis);
7189        }
7190    }
7191
7192    @Override
7193    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7194        enforceNotIsolatedCaller("takePersistableUriPermission");
7195
7196        Preconditions.checkFlagsArgument(modeFlags,
7197                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7198
7199        synchronized (this) {
7200            final int callingUid = Binder.getCallingUid();
7201            boolean persistChanged = false;
7202            GrantUri grantUri = new GrantUri(userId, uri, false);
7203
7204            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7205                    new GrantUri(userId, uri, false));
7206            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7207                    new GrantUri(userId, uri, true));
7208
7209            final boolean exactValid = (exactPerm != null)
7210                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7211            final boolean prefixValid = (prefixPerm != null)
7212                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7213
7214            if (!(exactValid || prefixValid)) {
7215                throw new SecurityException("No persistable permission grants found for UID "
7216                        + callingUid + " and Uri " + grantUri.toSafeString());
7217            }
7218
7219            if (exactValid) {
7220                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7221            }
7222            if (prefixValid) {
7223                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7224            }
7225
7226            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7227
7228            if (persistChanged) {
7229                schedulePersistUriGrants();
7230            }
7231        }
7232    }
7233
7234    @Override
7235    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7236        enforceNotIsolatedCaller("releasePersistableUriPermission");
7237
7238        Preconditions.checkFlagsArgument(modeFlags,
7239                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7240
7241        synchronized (this) {
7242            final int callingUid = Binder.getCallingUid();
7243            boolean persistChanged = false;
7244
7245            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7246                    new GrantUri(userId, uri, false));
7247            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7248                    new GrantUri(userId, uri, true));
7249            if (exactPerm == null && prefixPerm == null) {
7250                throw new SecurityException("No permission grants found for UID " + callingUid
7251                        + " and Uri " + uri.toSafeString());
7252            }
7253
7254            if (exactPerm != null) {
7255                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7256                removeUriPermissionIfNeededLocked(exactPerm);
7257            }
7258            if (prefixPerm != null) {
7259                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7260                removeUriPermissionIfNeededLocked(prefixPerm);
7261            }
7262
7263            if (persistChanged) {
7264                schedulePersistUriGrants();
7265            }
7266        }
7267    }
7268
7269    /**
7270     * Prune any older {@link UriPermission} for the given UID until outstanding
7271     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7272     *
7273     * @return if any mutations occured that require persisting.
7274     */
7275    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7276        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7277        if (perms == null) return false;
7278        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7279
7280        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7281        for (UriPermission perm : perms.values()) {
7282            if (perm.persistedModeFlags != 0) {
7283                persisted.add(perm);
7284            }
7285        }
7286
7287        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7288        if (trimCount <= 0) return false;
7289
7290        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7291        for (int i = 0; i < trimCount; i++) {
7292            final UriPermission perm = persisted.get(i);
7293
7294            if (DEBUG_URI_PERMISSION) {
7295                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7296            }
7297
7298            perm.releasePersistableModes(~0);
7299            removeUriPermissionIfNeededLocked(perm);
7300        }
7301
7302        return true;
7303    }
7304
7305    @Override
7306    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7307            String packageName, boolean incoming) {
7308        enforceNotIsolatedCaller("getPersistedUriPermissions");
7309        Preconditions.checkNotNull(packageName, "packageName");
7310
7311        final int callingUid = Binder.getCallingUid();
7312        final IPackageManager pm = AppGlobals.getPackageManager();
7313        try {
7314            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7315            if (packageUid != callingUid) {
7316                throw new SecurityException(
7317                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7318            }
7319        } catch (RemoteException e) {
7320            throw new SecurityException("Failed to verify package name ownership");
7321        }
7322
7323        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7324        synchronized (this) {
7325            if (incoming) {
7326                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7327                        callingUid);
7328                if (perms == null) {
7329                    Slog.w(TAG, "No permission grants found for " + packageName);
7330                } else {
7331                    for (UriPermission perm : perms.values()) {
7332                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7333                            result.add(perm.buildPersistedPublicApiObject());
7334                        }
7335                    }
7336                }
7337            } else {
7338                final int size = mGrantedUriPermissions.size();
7339                for (int i = 0; i < size; i++) {
7340                    final ArrayMap<GrantUri, UriPermission> perms =
7341                            mGrantedUriPermissions.valueAt(i);
7342                    for (UriPermission perm : perms.values()) {
7343                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7344                            result.add(perm.buildPersistedPublicApiObject());
7345                        }
7346                    }
7347                }
7348            }
7349        }
7350        return new ParceledListSlice<android.content.UriPermission>(result);
7351    }
7352
7353    @Override
7354    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7355        synchronized (this) {
7356            ProcessRecord app =
7357                who != null ? getRecordForAppLocked(who) : null;
7358            if (app == null) return;
7359
7360            Message msg = Message.obtain();
7361            msg.what = WAIT_FOR_DEBUGGER_MSG;
7362            msg.obj = app;
7363            msg.arg1 = waiting ? 1 : 0;
7364            mHandler.sendMessage(msg);
7365        }
7366    }
7367
7368    @Override
7369    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7370        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7371        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7372        outInfo.availMem = Process.getFreeMemory();
7373        outInfo.totalMem = Process.getTotalMemory();
7374        outInfo.threshold = homeAppMem;
7375        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7376        outInfo.hiddenAppThreshold = cachedAppMem;
7377        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7378                ProcessList.SERVICE_ADJ);
7379        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7380                ProcessList.VISIBLE_APP_ADJ);
7381        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7382                ProcessList.FOREGROUND_APP_ADJ);
7383    }
7384
7385    // =========================================================
7386    // TASK MANAGEMENT
7387    // =========================================================
7388
7389    @Override
7390    public List<IAppTask> getAppTasks() {
7391        final PackageManager pm = mContext.getPackageManager();
7392        int callingUid = Binder.getCallingUid();
7393        long ident = Binder.clearCallingIdentity();
7394
7395        // Compose the list of packages for this id to test against
7396        HashSet<String> packages = new HashSet<String>();
7397        String[] uidPackages = pm.getPackagesForUid(callingUid);
7398        for (int i = 0; i < uidPackages.length; i++) {
7399            packages.add(uidPackages[i]);
7400        }
7401
7402        synchronized(this) {
7403            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7404            try {
7405                if (localLOGV) Slog.v(TAG, "getAppTasks");
7406
7407                final int N = mRecentTasks.size();
7408                for (int i = 0; i < N; i++) {
7409                    TaskRecord tr = mRecentTasks.get(i);
7410                    // Skip tasks that are not created by the caller
7411                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7412                        ActivityManager.RecentTaskInfo taskInfo =
7413                                createRecentTaskInfoFromTaskRecord(tr);
7414                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7415                        list.add(taskImpl);
7416                    }
7417                }
7418            } finally {
7419                Binder.restoreCallingIdentity(ident);
7420            }
7421            return list;
7422        }
7423    }
7424
7425    @Override
7426    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7427        final int callingUid = Binder.getCallingUid();
7428        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7429
7430        synchronized(this) {
7431            if (localLOGV) Slog.v(
7432                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7433
7434            final boolean allowed = checkCallingPermission(
7435                    android.Manifest.permission.GET_TASKS)
7436                    == PackageManager.PERMISSION_GRANTED;
7437            if (!allowed) {
7438                Slog.w(TAG, "getTasks: caller " + callingUid
7439                        + " does not hold GET_TASKS; limiting output");
7440            }
7441
7442            // TODO: Improve with MRU list from all ActivityStacks.
7443            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7444        }
7445
7446        return list;
7447    }
7448
7449    TaskRecord getMostRecentTask() {
7450        return mRecentTasks.get(0);
7451    }
7452
7453    /**
7454     * Creates a new RecentTaskInfo from a TaskRecord.
7455     */
7456    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7457        // Update the task description to reflect any changes in the task stack
7458        tr.updateTaskDescription();
7459
7460        // Compose the recent task info
7461        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7462        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7463        rti.persistentId = tr.taskId;
7464        rti.baseIntent = new Intent(tr.getBaseIntent());
7465        rti.origActivity = tr.origActivity;
7466        rti.description = tr.lastDescription;
7467        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7468        rti.userId = tr.userId;
7469        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7470        rti.firstActiveTime = tr.firstActiveTime;
7471        rti.lastActiveTime = tr.lastActiveTime;
7472        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7473        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7474        return rti;
7475    }
7476
7477    @Override
7478    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7479        final int callingUid = Binder.getCallingUid();
7480        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7481                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7482
7483        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7484        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7485        synchronized (this) {
7486            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7487                    == PackageManager.PERMISSION_GRANTED;
7488            if (!allowed) {
7489                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7490                        + " does not hold GET_TASKS; limiting output");
7491            }
7492            final boolean detailed = checkCallingPermission(
7493                    android.Manifest.permission.GET_DETAILED_TASKS)
7494                    == PackageManager.PERMISSION_GRANTED;
7495
7496            IPackageManager pm = AppGlobals.getPackageManager();
7497
7498            final int N = mRecentTasks.size();
7499            ArrayList<ActivityManager.RecentTaskInfo> res
7500                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7501                            maxNum < N ? maxNum : N);
7502
7503            final Set<Integer> includedUsers;
7504            if (includeProfiles) {
7505                includedUsers = getProfileIdsLocked(userId);
7506            } else {
7507                includedUsers = new HashSet<Integer>();
7508            }
7509            includedUsers.add(Integer.valueOf(userId));
7510
7511            // Regroup affiliated tasks together.
7512            for (int i = 0; i < N; ) {
7513                TaskRecord task = mRecentTasks.remove(i);
7514                if (mTmpRecents.contains(task)) {
7515                    continue;
7516                }
7517                int affiliatedTaskId = task.mAffiliatedTaskId;
7518                while (true) {
7519                    TaskRecord next = task.mNextAffiliate;
7520                    if (next == null) {
7521                        break;
7522                    }
7523                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7524                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7525                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7526                        task.setNextAffiliate(null);
7527                        if (next.mPrevAffiliate == task) {
7528                            next.setPrevAffiliate(null);
7529                        }
7530                        break;
7531                    }
7532                    if (next.mPrevAffiliate != task) {
7533                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7534                                next.mPrevAffiliate + " task=" + task);
7535                        next.setPrevAffiliate(null);
7536                        break;
7537                    }
7538                    if (!mRecentTasks.contains(next)) {
7539                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7540                        task.setNextAffiliate(null);
7541                        if (next.mPrevAffiliate == task) {
7542                            next.setPrevAffiliate(null);
7543                        }
7544                        break;
7545                    }
7546                    task = next;
7547                }
7548                // task is now the end of the list
7549                do {
7550                    mRecentTasks.remove(task);
7551                    mRecentTasks.add(i++, task);
7552                    mTmpRecents.add(task);
7553                } while ((task = task.mPrevAffiliate) != null);
7554            }
7555            mTmpRecents.clear();
7556            // mRecentTasks is now in sorted, affiliated order.
7557
7558            for (int i=0; i<N && maxNum > 0; i++) {
7559                TaskRecord tr = mRecentTasks.get(i);
7560                // Only add calling user or related users recent tasks
7561                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7562
7563                // Return the entry if desired by the caller.  We always return
7564                // the first entry, because callers always expect this to be the
7565                // foreground app.  We may filter others if the caller has
7566                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7567                // we should exclude the entry.
7568
7569                if (i == 0
7570                        || withExcluded
7571                        || (tr.intent == null)
7572                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7573                                == 0)) {
7574                    if (!allowed) {
7575                        // If the caller doesn't have the GET_TASKS permission, then only
7576                        // allow them to see a small subset of tasks -- their own and home.
7577                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7578                            continue;
7579                        }
7580                    }
7581                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7582                        // Don't include auto remove tasks that are finished or finishing.
7583                        continue;
7584                    }
7585
7586                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7587                    if (!detailed) {
7588                        rti.baseIntent.replaceExtras((Bundle)null);
7589                    }
7590
7591                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7592                        // Check whether this activity is currently available.
7593                        try {
7594                            if (rti.origActivity != null) {
7595                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7596                                        == null) {
7597                                    continue;
7598                                }
7599                            } else if (rti.baseIntent != null) {
7600                                if (pm.queryIntentActivities(rti.baseIntent,
7601                                        null, 0, userId) == null) {
7602                                    continue;
7603                                }
7604                            }
7605                        } catch (RemoteException e) {
7606                            // Will never happen.
7607                        }
7608                    }
7609
7610                    res.add(rti);
7611                    maxNum--;
7612                }
7613            }
7614            return res;
7615        }
7616    }
7617
7618    private TaskRecord recentTaskForIdLocked(int id) {
7619        final int N = mRecentTasks.size();
7620            for (int i=0; i<N; i++) {
7621                TaskRecord tr = mRecentTasks.get(i);
7622                if (tr.taskId == id) {
7623                    return tr;
7624                }
7625            }
7626            return null;
7627    }
7628
7629    @Override
7630    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7631        synchronized (this) {
7632            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7633                    "getTaskThumbnail()");
7634            TaskRecord tr = recentTaskForIdLocked(id);
7635            if (tr != null) {
7636                return tr.getTaskThumbnailLocked();
7637            }
7638        }
7639        return null;
7640    }
7641
7642    @Override
7643    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7644        synchronized (this) {
7645            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7646            if (r != null) {
7647                r.taskDescription = td;
7648                r.task.updateTaskDescription();
7649            }
7650        }
7651    }
7652
7653    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7654        if (!pr.killedByAm) {
7655            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7656            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7657                    pr.processName, pr.setAdj, reason);
7658            pr.killedByAm = true;
7659            Process.killProcessQuiet(pr.pid);
7660            Process.killProcessGroup(pr.info.uid, pr.pid);
7661        }
7662    }
7663
7664    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7665        tr.disposeThumbnail();
7666        mRecentTasks.remove(tr);
7667        tr.closeRecentsChain();
7668        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7669        Intent baseIntent = new Intent(
7670                tr.intent != null ? tr.intent : tr.affinityIntent);
7671        ComponentName component = baseIntent.getComponent();
7672        if (component == null) {
7673            Slog.w(TAG, "Now component for base intent of task: " + tr);
7674            return;
7675        }
7676
7677        // Find any running services associated with this app.
7678        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7679
7680        if (killProcesses) {
7681            // Find any running processes associated with this app.
7682            final String pkg = component.getPackageName();
7683            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7684            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7685            for (int i=0; i<pmap.size(); i++) {
7686                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7687                for (int j=0; j<uids.size(); j++) {
7688                    ProcessRecord proc = uids.valueAt(j);
7689                    if (proc.userId != tr.userId) {
7690                        continue;
7691                    }
7692                    if (!proc.pkgList.containsKey(pkg)) {
7693                        continue;
7694                    }
7695                    procs.add(proc);
7696                }
7697            }
7698
7699            // Kill the running processes.
7700            for (int i=0; i<procs.size(); i++) {
7701                ProcessRecord pr = procs.get(i);
7702                if (pr == mHomeProcess) {
7703                    // Don't kill the home process along with tasks from the same package.
7704                    continue;
7705                }
7706                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7707                    killUnneededProcessLocked(pr, "remove task");
7708                } else {
7709                    pr.waitingToKill = "remove task";
7710                }
7711            }
7712        }
7713    }
7714
7715    /**
7716     * Removes the task with the specified task id.
7717     *
7718     * @param taskId Identifier of the task to be removed.
7719     * @param flags Additional operational flags.  May be 0 or
7720     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7721     * @return Returns true if the given task was found and removed.
7722     */
7723    private boolean removeTaskByIdLocked(int taskId, int flags) {
7724        TaskRecord tr = recentTaskForIdLocked(taskId);
7725        if (tr != null) {
7726            tr.removeTaskActivitiesLocked();
7727            cleanUpRemovedTaskLocked(tr, flags);
7728            if (tr.isPersistable) {
7729                notifyTaskPersisterLocked(null, true);
7730            }
7731            return true;
7732        }
7733        return false;
7734    }
7735
7736    @Override
7737    public boolean removeTask(int taskId, int flags) {
7738        synchronized (this) {
7739            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7740                    "removeTask()");
7741            long ident = Binder.clearCallingIdentity();
7742            try {
7743                return removeTaskByIdLocked(taskId, flags);
7744            } finally {
7745                Binder.restoreCallingIdentity(ident);
7746            }
7747        }
7748    }
7749
7750    /**
7751     * TODO: Add mController hook
7752     */
7753    @Override
7754    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7755        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7756                "moveTaskToFront()");
7757
7758        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7759        synchronized(this) {
7760            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7761                    Binder.getCallingUid(), "Task to front")) {
7762                ActivityOptions.abort(options);
7763                return;
7764            }
7765            final long origId = Binder.clearCallingIdentity();
7766            try {
7767                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7768                if (task == null) {
7769                    return;
7770                }
7771                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7772                    mStackSupervisor.showLockTaskToast();
7773                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7774                    return;
7775                }
7776                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7777                if (prev != null && prev.isRecentsActivity()) {
7778                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7779                }
7780                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7781            } finally {
7782                Binder.restoreCallingIdentity(origId);
7783            }
7784            ActivityOptions.abort(options);
7785        }
7786    }
7787
7788    @Override
7789    public void moveTaskToBack(int taskId) {
7790        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7791                "moveTaskToBack()");
7792
7793        synchronized(this) {
7794            TaskRecord tr = recentTaskForIdLocked(taskId);
7795            if (tr != null) {
7796                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7797                ActivityStack stack = tr.stack;
7798                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7799                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7800                            Binder.getCallingUid(), "Task to back")) {
7801                        return;
7802                    }
7803                }
7804                final long origId = Binder.clearCallingIdentity();
7805                try {
7806                    stack.moveTaskToBackLocked(taskId, null);
7807                } finally {
7808                    Binder.restoreCallingIdentity(origId);
7809                }
7810            }
7811        }
7812    }
7813
7814    /**
7815     * Moves an activity, and all of the other activities within the same task, to the bottom
7816     * of the history stack.  The activity's order within the task is unchanged.
7817     *
7818     * @param token A reference to the activity we wish to move
7819     * @param nonRoot If false then this only works if the activity is the root
7820     *                of a task; if true it will work for any activity in a task.
7821     * @return Returns true if the move completed, false if not.
7822     */
7823    @Override
7824    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7825        enforceNotIsolatedCaller("moveActivityTaskToBack");
7826        synchronized(this) {
7827            final long origId = Binder.clearCallingIdentity();
7828            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7829            if (taskId >= 0) {
7830                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7831            }
7832            Binder.restoreCallingIdentity(origId);
7833        }
7834        return false;
7835    }
7836
7837    @Override
7838    public void moveTaskBackwards(int task) {
7839        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7840                "moveTaskBackwards()");
7841
7842        synchronized(this) {
7843            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7844                    Binder.getCallingUid(), "Task backwards")) {
7845                return;
7846            }
7847            final long origId = Binder.clearCallingIdentity();
7848            moveTaskBackwardsLocked(task);
7849            Binder.restoreCallingIdentity(origId);
7850        }
7851    }
7852
7853    private final void moveTaskBackwardsLocked(int task) {
7854        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7855    }
7856
7857    @Override
7858    public IBinder getHomeActivityToken() throws RemoteException {
7859        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7860                "getHomeActivityToken()");
7861        synchronized (this) {
7862            return mStackSupervisor.getHomeActivityToken();
7863        }
7864    }
7865
7866    @Override
7867    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7868            IActivityContainerCallback callback) throws RemoteException {
7869        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7870                "createActivityContainer()");
7871        synchronized (this) {
7872            if (parentActivityToken == null) {
7873                throw new IllegalArgumentException("parent token must not be null");
7874            }
7875            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7876            if (r == null) {
7877                return null;
7878            }
7879            if (callback == null) {
7880                throw new IllegalArgumentException("callback must not be null");
7881            }
7882            return mStackSupervisor.createActivityContainer(r, callback);
7883        }
7884    }
7885
7886    @Override
7887    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7888        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7889                "deleteActivityContainer()");
7890        synchronized (this) {
7891            mStackSupervisor.deleteActivityContainer(container);
7892        }
7893    }
7894
7895    @Override
7896    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7897            throws RemoteException {
7898        synchronized (this) {
7899            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7900            if (stack != null) {
7901                return stack.mActivityContainer;
7902            }
7903            return null;
7904        }
7905    }
7906
7907    @Override
7908    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7909        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7910                "moveTaskToStack()");
7911        if (stackId == HOME_STACK_ID) {
7912            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7913                    new RuntimeException("here").fillInStackTrace());
7914        }
7915        synchronized (this) {
7916            long ident = Binder.clearCallingIdentity();
7917            try {
7918                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7919                        + stackId + " toTop=" + toTop);
7920                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7921            } finally {
7922                Binder.restoreCallingIdentity(ident);
7923            }
7924        }
7925    }
7926
7927    @Override
7928    public void resizeStack(int stackBoxId, Rect bounds) {
7929        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7930                "resizeStackBox()");
7931        long ident = Binder.clearCallingIdentity();
7932        try {
7933            mWindowManager.resizeStack(stackBoxId, bounds);
7934        } finally {
7935            Binder.restoreCallingIdentity(ident);
7936        }
7937    }
7938
7939    @Override
7940    public List<StackInfo> getAllStackInfos() {
7941        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7942                "getAllStackInfos()");
7943        long ident = Binder.clearCallingIdentity();
7944        try {
7945            synchronized (this) {
7946                return mStackSupervisor.getAllStackInfosLocked();
7947            }
7948        } finally {
7949            Binder.restoreCallingIdentity(ident);
7950        }
7951    }
7952
7953    @Override
7954    public StackInfo getStackInfo(int stackId) {
7955        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7956                "getStackInfo()");
7957        long ident = Binder.clearCallingIdentity();
7958        try {
7959            synchronized (this) {
7960                return mStackSupervisor.getStackInfoLocked(stackId);
7961            }
7962        } finally {
7963            Binder.restoreCallingIdentity(ident);
7964        }
7965    }
7966
7967    @Override
7968    public boolean isInHomeStack(int taskId) {
7969        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7970                "getStackInfo()");
7971        long ident = Binder.clearCallingIdentity();
7972        try {
7973            synchronized (this) {
7974                TaskRecord tr = recentTaskForIdLocked(taskId);
7975                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7976            }
7977        } finally {
7978            Binder.restoreCallingIdentity(ident);
7979        }
7980    }
7981
7982    @Override
7983    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7984        synchronized(this) {
7985            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7986        }
7987    }
7988
7989    private boolean isLockTaskAuthorized(String pkg) {
7990        final DevicePolicyManager dpm = (DevicePolicyManager)
7991                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7992        try {
7993            int uid = mContext.getPackageManager().getPackageUid(pkg,
7994                    Binder.getCallingUserHandle().getIdentifier());
7995            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7996        } catch (NameNotFoundException e) {
7997            return false;
7998        }
7999    }
8000
8001    void startLockTaskMode(TaskRecord task) {
8002        final String pkg;
8003        synchronized (this) {
8004            pkg = task.intent.getComponent().getPackageName();
8005        }
8006        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8007        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8008            final TaskRecord taskRecord = task;
8009            mHandler.post(new Runnable() {
8010                @Override
8011                public void run() {
8012                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8013                }
8014            });
8015            return;
8016        }
8017        long ident = Binder.clearCallingIdentity();
8018        try {
8019            synchronized (this) {
8020                // Since we lost lock on task, make sure it is still there.
8021                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8022                if (task != null) {
8023                    if (!isSystemInitiated
8024                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8025                        throw new IllegalArgumentException("Invalid task, not in foreground");
8026                    }
8027                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8028                }
8029            }
8030        } finally {
8031            Binder.restoreCallingIdentity(ident);
8032        }
8033    }
8034
8035    @Override
8036    public void startLockTaskMode(int taskId) {
8037        final TaskRecord task;
8038        long ident = Binder.clearCallingIdentity();
8039        try {
8040            synchronized (this) {
8041                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8042            }
8043        } finally {
8044            Binder.restoreCallingIdentity(ident);
8045        }
8046        if (task != null) {
8047            startLockTaskMode(task);
8048        }
8049    }
8050
8051    @Override
8052    public void startLockTaskMode(IBinder token) {
8053        final TaskRecord task;
8054        long ident = Binder.clearCallingIdentity();
8055        try {
8056            synchronized (this) {
8057                final ActivityRecord r = ActivityRecord.forToken(token);
8058                if (r == null) {
8059                    return;
8060                }
8061                task = r.task;
8062            }
8063        } finally {
8064            Binder.restoreCallingIdentity(ident);
8065        }
8066        if (task != null) {
8067            startLockTaskMode(task);
8068        }
8069    }
8070
8071    @Override
8072    public void startLockTaskModeOnCurrent() throws RemoteException {
8073        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8074        ActivityRecord r = null;
8075        synchronized (this) {
8076            r = mStackSupervisor.topRunningActivityLocked();
8077        }
8078        startLockTaskMode(r.task);
8079    }
8080
8081    @Override
8082    public void stopLockTaskMode() {
8083        // Verify that the user matches the package of the intent for the TaskRecord
8084        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8085        // and stopLockTaskMode.
8086        final int callingUid = Binder.getCallingUid();
8087        if (callingUid != Process.SYSTEM_UID) {
8088            try {
8089                String pkg =
8090                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8091                int uid = mContext.getPackageManager().getPackageUid(pkg,
8092                        Binder.getCallingUserHandle().getIdentifier());
8093                if (uid != callingUid) {
8094                    throw new SecurityException("Invalid uid, expected " + uid);
8095                }
8096            } catch (NameNotFoundException e) {
8097                Log.d(TAG, "stopLockTaskMode " + e);
8098                return;
8099            }
8100        }
8101        long ident = Binder.clearCallingIdentity();
8102        try {
8103            Log.d(TAG, "stopLockTaskMode");
8104            // Stop lock task
8105            synchronized (this) {
8106                mStackSupervisor.setLockTaskModeLocked(null, false);
8107            }
8108        } finally {
8109            Binder.restoreCallingIdentity(ident);
8110        }
8111    }
8112
8113    @Override
8114    public void stopLockTaskModeOnCurrent() throws RemoteException {
8115        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8116        long ident = Binder.clearCallingIdentity();
8117        try {
8118            stopLockTaskMode();
8119        } finally {
8120            Binder.restoreCallingIdentity(ident);
8121        }
8122    }
8123
8124    @Override
8125    public boolean isInLockTaskMode() {
8126        synchronized (this) {
8127            return mStackSupervisor.isInLockTaskMode();
8128        }
8129    }
8130
8131    // =========================================================
8132    // CONTENT PROVIDERS
8133    // =========================================================
8134
8135    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8136        List<ProviderInfo> providers = null;
8137        try {
8138            providers = AppGlobals.getPackageManager().
8139                queryContentProviders(app.processName, app.uid,
8140                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8141        } catch (RemoteException ex) {
8142        }
8143        if (DEBUG_MU)
8144            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8145        int userId = app.userId;
8146        if (providers != null) {
8147            int N = providers.size();
8148            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8149            for (int i=0; i<N; i++) {
8150                ProviderInfo cpi =
8151                    (ProviderInfo)providers.get(i);
8152                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8153                        cpi.name, cpi.flags);
8154                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8155                    // This is a singleton provider, but a user besides the
8156                    // default user is asking to initialize a process it runs
8157                    // in...  well, no, it doesn't actually run in this process,
8158                    // it runs in the process of the default user.  Get rid of it.
8159                    providers.remove(i);
8160                    N--;
8161                    i--;
8162                    continue;
8163                }
8164
8165                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8166                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8167                if (cpr == null) {
8168                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8169                    mProviderMap.putProviderByClass(comp, cpr);
8170                }
8171                if (DEBUG_MU)
8172                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8173                app.pubProviders.put(cpi.name, cpr);
8174                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8175                    // Don't add this if it is a platform component that is marked
8176                    // to run in multiple processes, because this is actually
8177                    // part of the framework so doesn't make sense to track as a
8178                    // separate apk in the process.
8179                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8180                            mProcessStats);
8181                }
8182                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8183            }
8184        }
8185        return providers;
8186    }
8187
8188    /**
8189     * Check if {@link ProcessRecord} has a possible chance at accessing the
8190     * given {@link ProviderInfo}. Final permission checking is always done
8191     * in {@link ContentProvider}.
8192     */
8193    private final String checkContentProviderPermissionLocked(
8194            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8195        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8196        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8197        boolean checkedGrants = false;
8198        if (checkUser) {
8199            // Looking for cross-user grants before enforcing the typical cross-users permissions
8200            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8201            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8202                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8203                    return null;
8204                }
8205                checkedGrants = true;
8206            }
8207            userId = handleIncomingUser(callingPid, callingUid, userId,
8208                    false, ALLOW_NON_FULL,
8209                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8210            if (userId != tmpTargetUserId) {
8211                // When we actually went to determine the final targer user ID, this ended
8212                // up different than our initial check for the authority.  This is because
8213                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8214                // SELF.  So we need to re-check the grants again.
8215                checkedGrants = false;
8216            }
8217        }
8218        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8219                cpi.applicationInfo.uid, cpi.exported)
8220                == PackageManager.PERMISSION_GRANTED) {
8221            return null;
8222        }
8223        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8224                cpi.applicationInfo.uid, cpi.exported)
8225                == PackageManager.PERMISSION_GRANTED) {
8226            return null;
8227        }
8228
8229        PathPermission[] pps = cpi.pathPermissions;
8230        if (pps != null) {
8231            int i = pps.length;
8232            while (i > 0) {
8233                i--;
8234                PathPermission pp = pps[i];
8235                String pprperm = pp.getReadPermission();
8236                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8237                        cpi.applicationInfo.uid, cpi.exported)
8238                        == PackageManager.PERMISSION_GRANTED) {
8239                    return null;
8240                }
8241                String ppwperm = pp.getWritePermission();
8242                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8243                        cpi.applicationInfo.uid, cpi.exported)
8244                        == PackageManager.PERMISSION_GRANTED) {
8245                    return null;
8246                }
8247            }
8248        }
8249        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8250            return null;
8251        }
8252
8253        String msg;
8254        if (!cpi.exported) {
8255            msg = "Permission Denial: opening provider " + cpi.name
8256                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8257                    + ", uid=" + callingUid + ") that is not exported from uid "
8258                    + cpi.applicationInfo.uid;
8259        } else {
8260            msg = "Permission Denial: opening provider " + cpi.name
8261                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8262                    + ", uid=" + callingUid + ") requires "
8263                    + cpi.readPermission + " or " + cpi.writePermission;
8264        }
8265        Slog.w(TAG, msg);
8266        return msg;
8267    }
8268
8269    /**
8270     * Returns if the ContentProvider has granted a uri to callingUid
8271     */
8272    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8273        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8274        if (perms != null) {
8275            for (int i=perms.size()-1; i>=0; i--) {
8276                GrantUri grantUri = perms.keyAt(i);
8277                if (grantUri.sourceUserId == userId || !checkUser) {
8278                    if (matchesProvider(grantUri.uri, cpi)) {
8279                        return true;
8280                    }
8281                }
8282            }
8283        }
8284        return false;
8285    }
8286
8287    /**
8288     * Returns true if the uri authority is one of the authorities specified in the provider.
8289     */
8290    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8291        String uriAuth = uri.getAuthority();
8292        String cpiAuth = cpi.authority;
8293        if (cpiAuth.indexOf(';') == -1) {
8294            return cpiAuth.equals(uriAuth);
8295        }
8296        String[] cpiAuths = cpiAuth.split(";");
8297        int length = cpiAuths.length;
8298        for (int i = 0; i < length; i++) {
8299            if (cpiAuths[i].equals(uriAuth)) return true;
8300        }
8301        return false;
8302    }
8303
8304    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8305            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8306        if (r != null) {
8307            for (int i=0; i<r.conProviders.size(); i++) {
8308                ContentProviderConnection conn = r.conProviders.get(i);
8309                if (conn.provider == cpr) {
8310                    if (DEBUG_PROVIDER) Slog.v(TAG,
8311                            "Adding provider requested by "
8312                            + r.processName + " from process "
8313                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8314                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8315                    if (stable) {
8316                        conn.stableCount++;
8317                        conn.numStableIncs++;
8318                    } else {
8319                        conn.unstableCount++;
8320                        conn.numUnstableIncs++;
8321                    }
8322                    return conn;
8323                }
8324            }
8325            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8326            if (stable) {
8327                conn.stableCount = 1;
8328                conn.numStableIncs = 1;
8329            } else {
8330                conn.unstableCount = 1;
8331                conn.numUnstableIncs = 1;
8332            }
8333            cpr.connections.add(conn);
8334            r.conProviders.add(conn);
8335            return conn;
8336        }
8337        cpr.addExternalProcessHandleLocked(externalProcessToken);
8338        return null;
8339    }
8340
8341    boolean decProviderCountLocked(ContentProviderConnection conn,
8342            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8343        if (conn != null) {
8344            cpr = conn.provider;
8345            if (DEBUG_PROVIDER) Slog.v(TAG,
8346                    "Removing provider requested by "
8347                    + conn.client.processName + " from process "
8348                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8349                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8350            if (stable) {
8351                conn.stableCount--;
8352            } else {
8353                conn.unstableCount--;
8354            }
8355            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8356                cpr.connections.remove(conn);
8357                conn.client.conProviders.remove(conn);
8358                return true;
8359            }
8360            return false;
8361        }
8362        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8363        return false;
8364    }
8365
8366    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8367            String name, IBinder token, boolean stable, int userId) {
8368        ContentProviderRecord cpr;
8369        ContentProviderConnection conn = null;
8370        ProviderInfo cpi = null;
8371
8372        synchronized(this) {
8373            ProcessRecord r = null;
8374            if (caller != null) {
8375                r = getRecordForAppLocked(caller);
8376                if (r == null) {
8377                    throw new SecurityException(
8378                            "Unable to find app for caller " + caller
8379                          + " (pid=" + Binder.getCallingPid()
8380                          + ") when getting content provider " + name);
8381                }
8382            }
8383
8384            boolean checkCrossUser = true;
8385
8386            // First check if this content provider has been published...
8387            cpr = mProviderMap.getProviderByName(name, userId);
8388            // If that didn't work, check if it exists for user 0 and then
8389            // verify that it's a singleton provider before using it.
8390            if (cpr == null && userId != UserHandle.USER_OWNER) {
8391                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8392                if (cpr != null) {
8393                    cpi = cpr.info;
8394                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8395                            cpi.name, cpi.flags)
8396                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8397                        userId = UserHandle.USER_OWNER;
8398                        checkCrossUser = false;
8399                    } else {
8400                        cpr = null;
8401                        cpi = null;
8402                    }
8403                }
8404            }
8405
8406            boolean providerRunning = cpr != null;
8407            if (providerRunning) {
8408                cpi = cpr.info;
8409                String msg;
8410                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8411                        != null) {
8412                    throw new SecurityException(msg);
8413                }
8414
8415                if (r != null && cpr.canRunHere(r)) {
8416                    // This provider has been published or is in the process
8417                    // of being published...  but it is also allowed to run
8418                    // in the caller's process, so don't make a connection
8419                    // and just let the caller instantiate its own instance.
8420                    ContentProviderHolder holder = cpr.newHolder(null);
8421                    // don't give caller the provider object, it needs
8422                    // to make its own.
8423                    holder.provider = null;
8424                    return holder;
8425                }
8426
8427                final long origId = Binder.clearCallingIdentity();
8428
8429                // In this case the provider instance already exists, so we can
8430                // return it right away.
8431                conn = incProviderCountLocked(r, cpr, token, stable);
8432                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8433                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8434                        // If this is a perceptible app accessing the provider,
8435                        // make sure to count it as being accessed and thus
8436                        // back up on the LRU list.  This is good because
8437                        // content providers are often expensive to start.
8438                        updateLruProcessLocked(cpr.proc, false, null);
8439                    }
8440                }
8441
8442                if (cpr.proc != null) {
8443                    if (false) {
8444                        if (cpr.name.flattenToShortString().equals(
8445                                "com.android.providers.calendar/.CalendarProvider2")) {
8446                            Slog.v(TAG, "****************** KILLING "
8447                                + cpr.name.flattenToShortString());
8448                            Process.killProcess(cpr.proc.pid);
8449                        }
8450                    }
8451                    boolean success = updateOomAdjLocked(cpr.proc);
8452                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8453                    // NOTE: there is still a race here where a signal could be
8454                    // pending on the process even though we managed to update its
8455                    // adj level.  Not sure what to do about this, but at least
8456                    // the race is now smaller.
8457                    if (!success) {
8458                        // Uh oh...  it looks like the provider's process
8459                        // has been killed on us.  We need to wait for a new
8460                        // process to be started, and make sure its death
8461                        // doesn't kill our process.
8462                        Slog.i(TAG,
8463                                "Existing provider " + cpr.name.flattenToShortString()
8464                                + " is crashing; detaching " + r);
8465                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8466                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8467                        if (!lastRef) {
8468                            // This wasn't the last ref our process had on
8469                            // the provider...  we have now been killed, bail.
8470                            return null;
8471                        }
8472                        providerRunning = false;
8473                        conn = null;
8474                    }
8475                }
8476
8477                Binder.restoreCallingIdentity(origId);
8478            }
8479
8480            boolean singleton;
8481            if (!providerRunning) {
8482                try {
8483                    cpi = AppGlobals.getPackageManager().
8484                        resolveContentProvider(name,
8485                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8486                } catch (RemoteException ex) {
8487                }
8488                if (cpi == null) {
8489                    return null;
8490                }
8491                // If the provider is a singleton AND
8492                // (it's a call within the same user || the provider is a
8493                // privileged app)
8494                // Then allow connecting to the singleton provider
8495                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8496                        cpi.name, cpi.flags)
8497                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8498                if (singleton) {
8499                    userId = UserHandle.USER_OWNER;
8500                }
8501                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8502
8503                String msg;
8504                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8505                        != null) {
8506                    throw new SecurityException(msg);
8507                }
8508
8509                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8510                        && !cpi.processName.equals("system")) {
8511                    // If this content provider does not run in the system
8512                    // process, and the system is not yet ready to run other
8513                    // processes, then fail fast instead of hanging.
8514                    throw new IllegalArgumentException(
8515                            "Attempt to launch content provider before system ready");
8516                }
8517
8518                // Make sure that the user who owns this provider is started.  If not,
8519                // we don't want to allow it to run.
8520                if (mStartedUsers.get(userId) == null) {
8521                    Slog.w(TAG, "Unable to launch app "
8522                            + cpi.applicationInfo.packageName + "/"
8523                            + cpi.applicationInfo.uid + " for provider "
8524                            + name + ": user " + userId + " is stopped");
8525                    return null;
8526                }
8527
8528                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8529                cpr = mProviderMap.getProviderByClass(comp, userId);
8530                final boolean firstClass = cpr == null;
8531                if (firstClass) {
8532                    try {
8533                        ApplicationInfo ai =
8534                            AppGlobals.getPackageManager().
8535                                getApplicationInfo(
8536                                        cpi.applicationInfo.packageName,
8537                                        STOCK_PM_FLAGS, userId);
8538                        if (ai == null) {
8539                            Slog.w(TAG, "No package info for content provider "
8540                                    + cpi.name);
8541                            return null;
8542                        }
8543                        ai = getAppInfoForUser(ai, userId);
8544                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8545                    } catch (RemoteException ex) {
8546                        // pm is in same process, this will never happen.
8547                    }
8548                }
8549
8550                if (r != null && cpr.canRunHere(r)) {
8551                    // If this is a multiprocess provider, then just return its
8552                    // info and allow the caller to instantiate it.  Only do
8553                    // this if the provider is the same user as the caller's
8554                    // process, or can run as root (so can be in any process).
8555                    return cpr.newHolder(null);
8556                }
8557
8558                if (DEBUG_PROVIDER) {
8559                    RuntimeException e = new RuntimeException("here");
8560                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8561                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8562                }
8563
8564                // This is single process, and our app is now connecting to it.
8565                // See if we are already in the process of launching this
8566                // provider.
8567                final int N = mLaunchingProviders.size();
8568                int i;
8569                for (i=0; i<N; i++) {
8570                    if (mLaunchingProviders.get(i) == cpr) {
8571                        break;
8572                    }
8573                }
8574
8575                // If the provider is not already being launched, then get it
8576                // started.
8577                if (i >= N) {
8578                    final long origId = Binder.clearCallingIdentity();
8579
8580                    try {
8581                        // Content provider is now in use, its package can't be stopped.
8582                        try {
8583                            AppGlobals.getPackageManager().setPackageStoppedState(
8584                                    cpr.appInfo.packageName, false, userId);
8585                        } catch (RemoteException e) {
8586                        } catch (IllegalArgumentException e) {
8587                            Slog.w(TAG, "Failed trying to unstop package "
8588                                    + cpr.appInfo.packageName + ": " + e);
8589                        }
8590
8591                        // Use existing process if already started
8592                        ProcessRecord proc = getProcessRecordLocked(
8593                                cpi.processName, cpr.appInfo.uid, false);
8594                        if (proc != null && proc.thread != null) {
8595                            if (DEBUG_PROVIDER) {
8596                                Slog.d(TAG, "Installing in existing process " + proc);
8597                            }
8598                            proc.pubProviders.put(cpi.name, cpr);
8599                            try {
8600                                proc.thread.scheduleInstallProvider(cpi);
8601                            } catch (RemoteException e) {
8602                            }
8603                        } else {
8604                            proc = startProcessLocked(cpi.processName,
8605                                    cpr.appInfo, false, 0, "content provider",
8606                                    new ComponentName(cpi.applicationInfo.packageName,
8607                                            cpi.name), false, false, false);
8608                            if (proc == null) {
8609                                Slog.w(TAG, "Unable to launch app "
8610                                        + cpi.applicationInfo.packageName + "/"
8611                                        + cpi.applicationInfo.uid + " for provider "
8612                                        + name + ": process is bad");
8613                                return null;
8614                            }
8615                        }
8616                        cpr.launchingApp = proc;
8617                        mLaunchingProviders.add(cpr);
8618                    } finally {
8619                        Binder.restoreCallingIdentity(origId);
8620                    }
8621                }
8622
8623                // Make sure the provider is published (the same provider class
8624                // may be published under multiple names).
8625                if (firstClass) {
8626                    mProviderMap.putProviderByClass(comp, cpr);
8627                }
8628
8629                mProviderMap.putProviderByName(name, cpr);
8630                conn = incProviderCountLocked(r, cpr, token, stable);
8631                if (conn != null) {
8632                    conn.waiting = true;
8633                }
8634            }
8635        }
8636
8637        // Wait for the provider to be published...
8638        synchronized (cpr) {
8639            while (cpr.provider == null) {
8640                if (cpr.launchingApp == null) {
8641                    Slog.w(TAG, "Unable to launch app "
8642                            + cpi.applicationInfo.packageName + "/"
8643                            + cpi.applicationInfo.uid + " for provider "
8644                            + name + ": launching app became null");
8645                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8646                            UserHandle.getUserId(cpi.applicationInfo.uid),
8647                            cpi.applicationInfo.packageName,
8648                            cpi.applicationInfo.uid, name);
8649                    return null;
8650                }
8651                try {
8652                    if (DEBUG_MU) {
8653                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8654                                + cpr.launchingApp);
8655                    }
8656                    if (conn != null) {
8657                        conn.waiting = true;
8658                    }
8659                    cpr.wait();
8660                } catch (InterruptedException ex) {
8661                } finally {
8662                    if (conn != null) {
8663                        conn.waiting = false;
8664                    }
8665                }
8666            }
8667        }
8668        return cpr != null ? cpr.newHolder(conn) : null;
8669    }
8670
8671    @Override
8672    public final ContentProviderHolder getContentProvider(
8673            IApplicationThread caller, String name, int userId, boolean stable) {
8674        enforceNotIsolatedCaller("getContentProvider");
8675        if (caller == null) {
8676            String msg = "null IApplicationThread when getting content provider "
8677                    + name;
8678            Slog.w(TAG, msg);
8679            throw new SecurityException(msg);
8680        }
8681        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8682        // with cross-user grant.
8683        return getContentProviderImpl(caller, name, null, stable, userId);
8684    }
8685
8686    public ContentProviderHolder getContentProviderExternal(
8687            String name, int userId, IBinder token) {
8688        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8689            "Do not have permission in call getContentProviderExternal()");
8690        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8691                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8692        return getContentProviderExternalUnchecked(name, token, userId);
8693    }
8694
8695    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8696            IBinder token, int userId) {
8697        return getContentProviderImpl(null, name, token, true, userId);
8698    }
8699
8700    /**
8701     * Drop a content provider from a ProcessRecord's bookkeeping
8702     */
8703    public void removeContentProvider(IBinder connection, boolean stable) {
8704        enforceNotIsolatedCaller("removeContentProvider");
8705        long ident = Binder.clearCallingIdentity();
8706        try {
8707            synchronized (this) {
8708                ContentProviderConnection conn;
8709                try {
8710                    conn = (ContentProviderConnection)connection;
8711                } catch (ClassCastException e) {
8712                    String msg ="removeContentProvider: " + connection
8713                            + " not a ContentProviderConnection";
8714                    Slog.w(TAG, msg);
8715                    throw new IllegalArgumentException(msg);
8716                }
8717                if (conn == null) {
8718                    throw new NullPointerException("connection is null");
8719                }
8720                if (decProviderCountLocked(conn, null, null, stable)) {
8721                    updateOomAdjLocked();
8722                }
8723            }
8724        } finally {
8725            Binder.restoreCallingIdentity(ident);
8726        }
8727    }
8728
8729    public void removeContentProviderExternal(String name, IBinder token) {
8730        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8731            "Do not have permission in call removeContentProviderExternal()");
8732        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8733    }
8734
8735    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8736        synchronized (this) {
8737            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8738            if(cpr == null) {
8739                //remove from mProvidersByClass
8740                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8741                return;
8742            }
8743
8744            //update content provider record entry info
8745            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8746            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8747            if (localCpr.hasExternalProcessHandles()) {
8748                if (localCpr.removeExternalProcessHandleLocked(token)) {
8749                    updateOomAdjLocked();
8750                } else {
8751                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8752                            + " with no external reference for token: "
8753                            + token + ".");
8754                }
8755            } else {
8756                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8757                        + " with no external references.");
8758            }
8759        }
8760    }
8761
8762    public final void publishContentProviders(IApplicationThread caller,
8763            List<ContentProviderHolder> providers) {
8764        if (providers == null) {
8765            return;
8766        }
8767
8768        enforceNotIsolatedCaller("publishContentProviders");
8769        synchronized (this) {
8770            final ProcessRecord r = getRecordForAppLocked(caller);
8771            if (DEBUG_MU)
8772                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8773            if (r == null) {
8774                throw new SecurityException(
8775                        "Unable to find app for caller " + caller
8776                      + " (pid=" + Binder.getCallingPid()
8777                      + ") when publishing content providers");
8778            }
8779
8780            final long origId = Binder.clearCallingIdentity();
8781
8782            final int N = providers.size();
8783            for (int i=0; i<N; i++) {
8784                ContentProviderHolder src = providers.get(i);
8785                if (src == null || src.info == null || src.provider == null) {
8786                    continue;
8787                }
8788                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8789                if (DEBUG_MU)
8790                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8791                if (dst != null) {
8792                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8793                    mProviderMap.putProviderByClass(comp, dst);
8794                    String names[] = dst.info.authority.split(";");
8795                    for (int j = 0; j < names.length; j++) {
8796                        mProviderMap.putProviderByName(names[j], dst);
8797                    }
8798
8799                    int NL = mLaunchingProviders.size();
8800                    int j;
8801                    for (j=0; j<NL; j++) {
8802                        if (mLaunchingProviders.get(j) == dst) {
8803                            mLaunchingProviders.remove(j);
8804                            j--;
8805                            NL--;
8806                        }
8807                    }
8808                    synchronized (dst) {
8809                        dst.provider = src.provider;
8810                        dst.proc = r;
8811                        dst.notifyAll();
8812                    }
8813                    updateOomAdjLocked(r);
8814                }
8815            }
8816
8817            Binder.restoreCallingIdentity(origId);
8818        }
8819    }
8820
8821    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8822        ContentProviderConnection conn;
8823        try {
8824            conn = (ContentProviderConnection)connection;
8825        } catch (ClassCastException e) {
8826            String msg ="refContentProvider: " + connection
8827                    + " not a ContentProviderConnection";
8828            Slog.w(TAG, msg);
8829            throw new IllegalArgumentException(msg);
8830        }
8831        if (conn == null) {
8832            throw new NullPointerException("connection is null");
8833        }
8834
8835        synchronized (this) {
8836            if (stable > 0) {
8837                conn.numStableIncs += stable;
8838            }
8839            stable = conn.stableCount + stable;
8840            if (stable < 0) {
8841                throw new IllegalStateException("stableCount < 0: " + stable);
8842            }
8843
8844            if (unstable > 0) {
8845                conn.numUnstableIncs += unstable;
8846            }
8847            unstable = conn.unstableCount + unstable;
8848            if (unstable < 0) {
8849                throw new IllegalStateException("unstableCount < 0: " + unstable);
8850            }
8851
8852            if ((stable+unstable) <= 0) {
8853                throw new IllegalStateException("ref counts can't go to zero here: stable="
8854                        + stable + " unstable=" + unstable);
8855            }
8856            conn.stableCount = stable;
8857            conn.unstableCount = unstable;
8858            return !conn.dead;
8859        }
8860    }
8861
8862    public void unstableProviderDied(IBinder connection) {
8863        ContentProviderConnection conn;
8864        try {
8865            conn = (ContentProviderConnection)connection;
8866        } catch (ClassCastException e) {
8867            String msg ="refContentProvider: " + connection
8868                    + " not a ContentProviderConnection";
8869            Slog.w(TAG, msg);
8870            throw new IllegalArgumentException(msg);
8871        }
8872        if (conn == null) {
8873            throw new NullPointerException("connection is null");
8874        }
8875
8876        // Safely retrieve the content provider associated with the connection.
8877        IContentProvider provider;
8878        synchronized (this) {
8879            provider = conn.provider.provider;
8880        }
8881
8882        if (provider == null) {
8883            // Um, yeah, we're way ahead of you.
8884            return;
8885        }
8886
8887        // Make sure the caller is being honest with us.
8888        if (provider.asBinder().pingBinder()) {
8889            // Er, no, still looks good to us.
8890            synchronized (this) {
8891                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8892                        + " says " + conn + " died, but we don't agree");
8893                return;
8894            }
8895        }
8896
8897        // Well look at that!  It's dead!
8898        synchronized (this) {
8899            if (conn.provider.provider != provider) {
8900                // But something changed...  good enough.
8901                return;
8902            }
8903
8904            ProcessRecord proc = conn.provider.proc;
8905            if (proc == null || proc.thread == null) {
8906                // Seems like the process is already cleaned up.
8907                return;
8908            }
8909
8910            // As far as we're concerned, this is just like receiving a
8911            // death notification...  just a bit prematurely.
8912            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8913                    + ") early provider death");
8914            final long ident = Binder.clearCallingIdentity();
8915            try {
8916                appDiedLocked(proc, proc.pid, proc.thread);
8917            } finally {
8918                Binder.restoreCallingIdentity(ident);
8919            }
8920        }
8921    }
8922
8923    @Override
8924    public void appNotRespondingViaProvider(IBinder connection) {
8925        enforceCallingPermission(
8926                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8927
8928        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8929        if (conn == null) {
8930            Slog.w(TAG, "ContentProviderConnection is null");
8931            return;
8932        }
8933
8934        final ProcessRecord host = conn.provider.proc;
8935        if (host == null) {
8936            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8937            return;
8938        }
8939
8940        final long token = Binder.clearCallingIdentity();
8941        try {
8942            appNotResponding(host, null, null, false, "ContentProvider not responding");
8943        } finally {
8944            Binder.restoreCallingIdentity(token);
8945        }
8946    }
8947
8948    public final void installSystemProviders() {
8949        List<ProviderInfo> providers;
8950        synchronized (this) {
8951            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8952            providers = generateApplicationProvidersLocked(app);
8953            if (providers != null) {
8954                for (int i=providers.size()-1; i>=0; i--) {
8955                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8956                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8957                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8958                                + ": not system .apk");
8959                        providers.remove(i);
8960                    }
8961                }
8962            }
8963        }
8964        if (providers != null) {
8965            mSystemThread.installSystemProviders(providers);
8966        }
8967
8968        mCoreSettingsObserver = new CoreSettingsObserver(this);
8969
8970        //mUsageStatsService.monitorPackages();
8971    }
8972
8973    /**
8974     * Allows app to retrieve the MIME type of a URI without having permission
8975     * to access its content provider.
8976     *
8977     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8978     *
8979     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8980     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8981     */
8982    public String getProviderMimeType(Uri uri, int userId) {
8983        enforceNotIsolatedCaller("getProviderMimeType");
8984        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8985                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8986        final String name = uri.getAuthority();
8987        final long ident = Binder.clearCallingIdentity();
8988        ContentProviderHolder holder = null;
8989
8990        try {
8991            holder = getContentProviderExternalUnchecked(name, null, userId);
8992            if (holder != null) {
8993                return holder.provider.getType(uri);
8994            }
8995        } catch (RemoteException e) {
8996            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8997            return null;
8998        } finally {
8999            if (holder != null) {
9000                removeContentProviderExternalUnchecked(name, null, userId);
9001            }
9002            Binder.restoreCallingIdentity(ident);
9003        }
9004
9005        return null;
9006    }
9007
9008    // =========================================================
9009    // GLOBAL MANAGEMENT
9010    // =========================================================
9011
9012    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9013            boolean isolated, int isolatedUid) {
9014        String proc = customProcess != null ? customProcess : info.processName;
9015        BatteryStatsImpl.Uid.Proc ps = null;
9016        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9017        int uid = info.uid;
9018        if (isolated) {
9019            if (isolatedUid == 0) {
9020                int userId = UserHandle.getUserId(uid);
9021                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9022                while (true) {
9023                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9024                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9025                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9026                    }
9027                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9028                    mNextIsolatedProcessUid++;
9029                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9030                        // No process for this uid, use it.
9031                        break;
9032                    }
9033                    stepsLeft--;
9034                    if (stepsLeft <= 0) {
9035                        return null;
9036                    }
9037                }
9038            } else {
9039                // Special case for startIsolatedProcess (internal only), where
9040                // the uid of the isolated process is specified by the caller.
9041                uid = isolatedUid;
9042            }
9043        }
9044        return new ProcessRecord(stats, info, proc, uid);
9045    }
9046
9047    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9048            String abiOverride) {
9049        ProcessRecord app;
9050        if (!isolated) {
9051            app = getProcessRecordLocked(info.processName, info.uid, true);
9052        } else {
9053            app = null;
9054        }
9055
9056        if (app == null) {
9057            app = newProcessRecordLocked(info, null, isolated, 0);
9058            mProcessNames.put(info.processName, app.uid, app);
9059            if (isolated) {
9060                mIsolatedProcesses.put(app.uid, app);
9061            }
9062            updateLruProcessLocked(app, false, null);
9063            updateOomAdjLocked();
9064        }
9065
9066        // This package really, really can not be stopped.
9067        try {
9068            AppGlobals.getPackageManager().setPackageStoppedState(
9069                    info.packageName, false, UserHandle.getUserId(app.uid));
9070        } catch (RemoteException e) {
9071        } catch (IllegalArgumentException e) {
9072            Slog.w(TAG, "Failed trying to unstop package "
9073                    + info.packageName + ": " + e);
9074        }
9075
9076        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9077                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9078            app.persistent = true;
9079            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9080        }
9081        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9082            mPersistentStartingProcesses.add(app);
9083            startProcessLocked(app, "added application", app.processName, abiOverride,
9084                    null /* entryPoint */, null /* entryPointArgs */);
9085        }
9086
9087        return app;
9088    }
9089
9090    public void unhandledBack() {
9091        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9092                "unhandledBack()");
9093
9094        synchronized(this) {
9095            final long origId = Binder.clearCallingIdentity();
9096            try {
9097                getFocusedStack().unhandledBackLocked();
9098            } finally {
9099                Binder.restoreCallingIdentity(origId);
9100            }
9101        }
9102    }
9103
9104    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9105        enforceNotIsolatedCaller("openContentUri");
9106        final int userId = UserHandle.getCallingUserId();
9107        String name = uri.getAuthority();
9108        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9109        ParcelFileDescriptor pfd = null;
9110        if (cph != null) {
9111            // We record the binder invoker's uid in thread-local storage before
9112            // going to the content provider to open the file.  Later, in the code
9113            // that handles all permissions checks, we look for this uid and use
9114            // that rather than the Activity Manager's own uid.  The effect is that
9115            // we do the check against the caller's permissions even though it looks
9116            // to the content provider like the Activity Manager itself is making
9117            // the request.
9118            sCallerIdentity.set(new Identity(
9119                    Binder.getCallingPid(), Binder.getCallingUid()));
9120            try {
9121                pfd = cph.provider.openFile(null, uri, "r", null);
9122            } catch (FileNotFoundException e) {
9123                // do nothing; pfd will be returned null
9124            } finally {
9125                // Ensure that whatever happens, we clean up the identity state
9126                sCallerIdentity.remove();
9127            }
9128
9129            // We've got the fd now, so we're done with the provider.
9130            removeContentProviderExternalUnchecked(name, null, userId);
9131        } else {
9132            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9133        }
9134        return pfd;
9135    }
9136
9137    // Actually is sleeping or shutting down or whatever else in the future
9138    // is an inactive state.
9139    public boolean isSleepingOrShuttingDown() {
9140        return mSleeping || mShuttingDown;
9141    }
9142
9143    public boolean isSleeping() {
9144        return mSleeping;
9145    }
9146
9147    void goingToSleep() {
9148        synchronized(this) {
9149            mWentToSleep = true;
9150            updateEventDispatchingLocked();
9151            goToSleepIfNeededLocked();
9152        }
9153    }
9154
9155    void finishRunningVoiceLocked() {
9156        if (mRunningVoice) {
9157            mRunningVoice = false;
9158            goToSleepIfNeededLocked();
9159        }
9160    }
9161
9162    void goToSleepIfNeededLocked() {
9163        if (mWentToSleep && !mRunningVoice) {
9164            if (!mSleeping) {
9165                mSleeping = true;
9166                mStackSupervisor.goingToSleepLocked();
9167
9168                // Initialize the wake times of all processes.
9169                checkExcessivePowerUsageLocked(false);
9170                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9171                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9172                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9173            }
9174        }
9175    }
9176
9177    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9178        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9179            // Never persist the home stack.
9180            return;
9181        }
9182        mTaskPersister.wakeup(task, flush);
9183    }
9184
9185    @Override
9186    public boolean shutdown(int timeout) {
9187        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9188                != PackageManager.PERMISSION_GRANTED) {
9189            throw new SecurityException("Requires permission "
9190                    + android.Manifest.permission.SHUTDOWN);
9191        }
9192
9193        boolean timedout = false;
9194
9195        synchronized(this) {
9196            mShuttingDown = true;
9197            updateEventDispatchingLocked();
9198            timedout = mStackSupervisor.shutdownLocked(timeout);
9199        }
9200
9201        mAppOpsService.shutdown();
9202        if (mUsageStatsService != null) {
9203            mUsageStatsService.prepareShutdown();
9204        }
9205        mBatteryStatsService.shutdown();
9206        synchronized (this) {
9207            mProcessStats.shutdownLocked();
9208        }
9209        notifyTaskPersisterLocked(null, true);
9210
9211        return timedout;
9212    }
9213
9214    public final void activitySlept(IBinder token) {
9215        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9216
9217        final long origId = Binder.clearCallingIdentity();
9218
9219        synchronized (this) {
9220            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9221            if (r != null) {
9222                mStackSupervisor.activitySleptLocked(r);
9223            }
9224        }
9225
9226        Binder.restoreCallingIdentity(origId);
9227    }
9228
9229    void logLockScreen(String msg) {
9230        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9231                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9232                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9233                mStackSupervisor.mDismissKeyguardOnNextActivity);
9234    }
9235
9236    private void comeOutOfSleepIfNeededLocked() {
9237        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9238            if (mSleeping) {
9239                mSleeping = false;
9240                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9241            }
9242        }
9243    }
9244
9245    void wakingUp() {
9246        synchronized(this) {
9247            mWentToSleep = false;
9248            updateEventDispatchingLocked();
9249            comeOutOfSleepIfNeededLocked();
9250        }
9251    }
9252
9253    void startRunningVoiceLocked() {
9254        if (!mRunningVoice) {
9255            mRunningVoice = true;
9256            comeOutOfSleepIfNeededLocked();
9257        }
9258    }
9259
9260    private void updateEventDispatchingLocked() {
9261        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9262    }
9263
9264    public void setLockScreenShown(boolean shown) {
9265        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9266                != PackageManager.PERMISSION_GRANTED) {
9267            throw new SecurityException("Requires permission "
9268                    + android.Manifest.permission.DEVICE_POWER);
9269        }
9270
9271        synchronized(this) {
9272            long ident = Binder.clearCallingIdentity();
9273            try {
9274                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9275                mLockScreenShown = shown;
9276                comeOutOfSleepIfNeededLocked();
9277            } finally {
9278                Binder.restoreCallingIdentity(ident);
9279            }
9280        }
9281    }
9282
9283    @Override
9284    public void stopAppSwitches() {
9285        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9286                != PackageManager.PERMISSION_GRANTED) {
9287            throw new SecurityException("Requires permission "
9288                    + android.Manifest.permission.STOP_APP_SWITCHES);
9289        }
9290
9291        synchronized(this) {
9292            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9293                    + APP_SWITCH_DELAY_TIME;
9294            mDidAppSwitch = false;
9295            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9296            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9297            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9298        }
9299    }
9300
9301    public void resumeAppSwitches() {
9302        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9303                != PackageManager.PERMISSION_GRANTED) {
9304            throw new SecurityException("Requires permission "
9305                    + android.Manifest.permission.STOP_APP_SWITCHES);
9306        }
9307
9308        synchronized(this) {
9309            // Note that we don't execute any pending app switches... we will
9310            // let those wait until either the timeout, or the next start
9311            // activity request.
9312            mAppSwitchesAllowedTime = 0;
9313        }
9314    }
9315
9316    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9317            String name) {
9318        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9319            return true;
9320        }
9321
9322        final int perm = checkComponentPermission(
9323                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9324                callingUid, -1, true);
9325        if (perm == PackageManager.PERMISSION_GRANTED) {
9326            return true;
9327        }
9328
9329        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9330        return false;
9331    }
9332
9333    public void setDebugApp(String packageName, boolean waitForDebugger,
9334            boolean persistent) {
9335        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9336                "setDebugApp()");
9337
9338        long ident = Binder.clearCallingIdentity();
9339        try {
9340            // Note that this is not really thread safe if there are multiple
9341            // callers into it at the same time, but that's not a situation we
9342            // care about.
9343            if (persistent) {
9344                final ContentResolver resolver = mContext.getContentResolver();
9345                Settings.Global.putString(
9346                    resolver, Settings.Global.DEBUG_APP,
9347                    packageName);
9348                Settings.Global.putInt(
9349                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9350                    waitForDebugger ? 1 : 0);
9351            }
9352
9353            synchronized (this) {
9354                if (!persistent) {
9355                    mOrigDebugApp = mDebugApp;
9356                    mOrigWaitForDebugger = mWaitForDebugger;
9357                }
9358                mDebugApp = packageName;
9359                mWaitForDebugger = waitForDebugger;
9360                mDebugTransient = !persistent;
9361                if (packageName != null) {
9362                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9363                            false, UserHandle.USER_ALL, "set debug app");
9364                }
9365            }
9366        } finally {
9367            Binder.restoreCallingIdentity(ident);
9368        }
9369    }
9370
9371    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9372        synchronized (this) {
9373            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9374            if (!isDebuggable) {
9375                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9376                    throw new SecurityException("Process not debuggable: " + app.packageName);
9377                }
9378            }
9379
9380            mOpenGlTraceApp = processName;
9381        }
9382    }
9383
9384    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9385            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9386        synchronized (this) {
9387            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9388            if (!isDebuggable) {
9389                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9390                    throw new SecurityException("Process not debuggable: " + app.packageName);
9391                }
9392            }
9393            mProfileApp = processName;
9394            mProfileFile = profileFile;
9395            if (mProfileFd != null) {
9396                try {
9397                    mProfileFd.close();
9398                } catch (IOException e) {
9399                }
9400                mProfileFd = null;
9401            }
9402            mProfileFd = profileFd;
9403            mProfileType = 0;
9404            mAutoStopProfiler = autoStopProfiler;
9405        }
9406    }
9407
9408    @Override
9409    public void setAlwaysFinish(boolean enabled) {
9410        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9411                "setAlwaysFinish()");
9412
9413        Settings.Global.putInt(
9414                mContext.getContentResolver(),
9415                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9416
9417        synchronized (this) {
9418            mAlwaysFinishActivities = enabled;
9419        }
9420    }
9421
9422    @Override
9423    public void setActivityController(IActivityController controller) {
9424        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9425                "setActivityController()");
9426        synchronized (this) {
9427            mController = controller;
9428            Watchdog.getInstance().setActivityController(controller);
9429        }
9430    }
9431
9432    @Override
9433    public void setUserIsMonkey(boolean userIsMonkey) {
9434        synchronized (this) {
9435            synchronized (mPidsSelfLocked) {
9436                final int callingPid = Binder.getCallingPid();
9437                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9438                if (precessRecord == null) {
9439                    throw new SecurityException("Unknown process: " + callingPid);
9440                }
9441                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9442                    throw new SecurityException("Only an instrumentation process "
9443                            + "with a UiAutomation can call setUserIsMonkey");
9444                }
9445            }
9446            mUserIsMonkey = userIsMonkey;
9447        }
9448    }
9449
9450    @Override
9451    public boolean isUserAMonkey() {
9452        synchronized (this) {
9453            // If there is a controller also implies the user is a monkey.
9454            return (mUserIsMonkey || mController != null);
9455        }
9456    }
9457
9458    public void requestBugReport() {
9459        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9460        SystemProperties.set("ctl.start", "bugreport");
9461    }
9462
9463    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9464        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9465    }
9466
9467    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9468        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9469            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9470        }
9471        return KEY_DISPATCHING_TIMEOUT;
9472    }
9473
9474    @Override
9475    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9476        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9477                != PackageManager.PERMISSION_GRANTED) {
9478            throw new SecurityException("Requires permission "
9479                    + android.Manifest.permission.FILTER_EVENTS);
9480        }
9481        ProcessRecord proc;
9482        long timeout;
9483        synchronized (this) {
9484            synchronized (mPidsSelfLocked) {
9485                proc = mPidsSelfLocked.get(pid);
9486            }
9487            timeout = getInputDispatchingTimeoutLocked(proc);
9488        }
9489
9490        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9491            return -1;
9492        }
9493
9494        return timeout;
9495    }
9496
9497    /**
9498     * Handle input dispatching timeouts.
9499     * Returns whether input dispatching should be aborted or not.
9500     */
9501    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9502            final ActivityRecord activity, final ActivityRecord parent,
9503            final boolean aboveSystem, String reason) {
9504        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9505                != PackageManager.PERMISSION_GRANTED) {
9506            throw new SecurityException("Requires permission "
9507                    + android.Manifest.permission.FILTER_EVENTS);
9508        }
9509
9510        final String annotation;
9511        if (reason == null) {
9512            annotation = "Input dispatching timed out";
9513        } else {
9514            annotation = "Input dispatching timed out (" + reason + ")";
9515        }
9516
9517        if (proc != null) {
9518            synchronized (this) {
9519                if (proc.debugging) {
9520                    return false;
9521                }
9522
9523                if (mDidDexOpt) {
9524                    // Give more time since we were dexopting.
9525                    mDidDexOpt = false;
9526                    return false;
9527                }
9528
9529                if (proc.instrumentationClass != null) {
9530                    Bundle info = new Bundle();
9531                    info.putString("shortMsg", "keyDispatchingTimedOut");
9532                    info.putString("longMsg", annotation);
9533                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9534                    return true;
9535                }
9536            }
9537            mHandler.post(new Runnable() {
9538                @Override
9539                public void run() {
9540                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9541                }
9542            });
9543        }
9544
9545        return true;
9546    }
9547
9548    public Bundle getAssistContextExtras(int requestType) {
9549        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9550                "getAssistContextExtras()");
9551        PendingAssistExtras pae;
9552        Bundle extras = new Bundle();
9553        synchronized (this) {
9554            ActivityRecord activity = getFocusedStack().mResumedActivity;
9555            if (activity == null) {
9556                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9557                return null;
9558            }
9559            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9560            if (activity.app == null || activity.app.thread == null) {
9561                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9562                return extras;
9563            }
9564            if (activity.app.pid == Binder.getCallingPid()) {
9565                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9566                return extras;
9567            }
9568            pae = new PendingAssistExtras(activity);
9569            try {
9570                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9571                        requestType);
9572                mPendingAssistExtras.add(pae);
9573                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9574            } catch (RemoteException e) {
9575                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9576                return extras;
9577            }
9578        }
9579        synchronized (pae) {
9580            while (!pae.haveResult) {
9581                try {
9582                    pae.wait();
9583                } catch (InterruptedException e) {
9584                }
9585            }
9586            if (pae.result != null) {
9587                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9588            }
9589        }
9590        synchronized (this) {
9591            mPendingAssistExtras.remove(pae);
9592            mHandler.removeCallbacks(pae);
9593        }
9594        return extras;
9595    }
9596
9597    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9598        PendingAssistExtras pae = (PendingAssistExtras)token;
9599        synchronized (pae) {
9600            pae.result = extras;
9601            pae.haveResult = true;
9602            pae.notifyAll();
9603        }
9604    }
9605
9606    public void registerProcessObserver(IProcessObserver observer) {
9607        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9608                "registerProcessObserver()");
9609        synchronized (this) {
9610            mProcessObservers.register(observer);
9611        }
9612    }
9613
9614    @Override
9615    public void unregisterProcessObserver(IProcessObserver observer) {
9616        synchronized (this) {
9617            mProcessObservers.unregister(observer);
9618        }
9619    }
9620
9621    @Override
9622    public boolean convertFromTranslucent(IBinder token) {
9623        final long origId = Binder.clearCallingIdentity();
9624        try {
9625            synchronized (this) {
9626                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9627                if (r == null) {
9628                    return false;
9629                }
9630                if (r.changeWindowTranslucency(true)) {
9631                    mWindowManager.setAppFullscreen(token, true);
9632                    r.task.stack.releaseMediaResources();
9633                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9634                    return true;
9635                }
9636                return false;
9637            }
9638        } finally {
9639            Binder.restoreCallingIdentity(origId);
9640        }
9641    }
9642
9643    @Override
9644    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9645        final long origId = Binder.clearCallingIdentity();
9646        try {
9647            synchronized (this) {
9648                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9649                if (r == null) {
9650                    return false;
9651                }
9652                int index = r.task.mActivities.lastIndexOf(r);
9653                if (index > 0) {
9654                    ActivityRecord under = r.task.mActivities.get(index - 1);
9655                    under.returningOptions = options;
9656                }
9657                if (r.changeWindowTranslucency(false)) {
9658                    r.task.stack.convertToTranslucent(r);
9659                    mWindowManager.setAppFullscreen(token, false);
9660                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9661                    return true;
9662                } else {
9663                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9664                    return false;
9665                }
9666            }
9667        } finally {
9668            Binder.restoreCallingIdentity(origId);
9669        }
9670    }
9671
9672    @Override
9673    public boolean setMediaPlaying(IBinder token, boolean playing) {
9674        final long origId = Binder.clearCallingIdentity();
9675        try {
9676            synchronized (this) {
9677                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9678                if (r != null) {
9679                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9680                }
9681            }
9682            return false;
9683        } finally {
9684            Binder.restoreCallingIdentity(origId);
9685        }
9686    }
9687
9688    @Override
9689    public boolean isBackgroundMediaPlaying(IBinder token) {
9690        final long origId = Binder.clearCallingIdentity();
9691        try {
9692            synchronized (this) {
9693                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9694                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9695                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9696                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9697                return playing;
9698            }
9699        } finally {
9700            Binder.restoreCallingIdentity(origId);
9701        }
9702    }
9703
9704    @Override
9705    public ActivityOptions getActivityOptions(IBinder token) {
9706        final long origId = Binder.clearCallingIdentity();
9707        try {
9708            synchronized (this) {
9709                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9710                if (r != null) {
9711                    final ActivityOptions activityOptions = r.pendingOptions;
9712                    r.pendingOptions = null;
9713                    return activityOptions;
9714                }
9715                return null;
9716            }
9717        } finally {
9718            Binder.restoreCallingIdentity(origId);
9719        }
9720    }
9721
9722    @Override
9723    public void setImmersive(IBinder token, boolean immersive) {
9724        synchronized(this) {
9725            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9726            if (r == null) {
9727                throw new IllegalArgumentException();
9728            }
9729            r.immersive = immersive;
9730
9731            // update associated state if we're frontmost
9732            if (r == mFocusedActivity) {
9733                if (DEBUG_IMMERSIVE) {
9734                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9735                }
9736                applyUpdateLockStateLocked(r);
9737            }
9738        }
9739    }
9740
9741    @Override
9742    public boolean isImmersive(IBinder token) {
9743        synchronized (this) {
9744            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9745            if (r == null) {
9746                throw new IllegalArgumentException();
9747            }
9748            return r.immersive;
9749        }
9750    }
9751
9752    public boolean isTopActivityImmersive() {
9753        enforceNotIsolatedCaller("startActivity");
9754        synchronized (this) {
9755            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9756            return (r != null) ? r.immersive : false;
9757        }
9758    }
9759
9760    @Override
9761    public boolean isTopOfTask(IBinder token) {
9762        synchronized (this) {
9763            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9764            if (r == null) {
9765                throw new IllegalArgumentException();
9766            }
9767            return r.task.getTopActivity() == r;
9768        }
9769    }
9770
9771    public final void enterSafeMode() {
9772        synchronized(this) {
9773            // It only makes sense to do this before the system is ready
9774            // and started launching other packages.
9775            if (!mSystemReady) {
9776                try {
9777                    AppGlobals.getPackageManager().enterSafeMode();
9778                } catch (RemoteException e) {
9779                }
9780            }
9781
9782            mSafeMode = true;
9783        }
9784    }
9785
9786    public final void showSafeModeOverlay() {
9787        View v = LayoutInflater.from(mContext).inflate(
9788                com.android.internal.R.layout.safe_mode, null);
9789        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9790        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9791        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9792        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9793        lp.gravity = Gravity.BOTTOM | Gravity.START;
9794        lp.format = v.getBackground().getOpacity();
9795        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9796                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9797        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9798        ((WindowManager)mContext.getSystemService(
9799                Context.WINDOW_SERVICE)).addView(v, lp);
9800    }
9801
9802    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9803        if (!(sender instanceof PendingIntentRecord)) {
9804            return;
9805        }
9806        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9807        synchronized (stats) {
9808            if (mBatteryStatsService.isOnBattery()) {
9809                mBatteryStatsService.enforceCallingPermission();
9810                PendingIntentRecord rec = (PendingIntentRecord)sender;
9811                int MY_UID = Binder.getCallingUid();
9812                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9813                BatteryStatsImpl.Uid.Pkg pkg =
9814                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9815                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9816                pkg.incWakeupsLocked();
9817            }
9818        }
9819    }
9820
9821    public boolean killPids(int[] pids, String pReason, boolean secure) {
9822        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9823            throw new SecurityException("killPids only available to the system");
9824        }
9825        String reason = (pReason == null) ? "Unknown" : pReason;
9826        // XXX Note: don't acquire main activity lock here, because the window
9827        // manager calls in with its locks held.
9828
9829        boolean killed = false;
9830        synchronized (mPidsSelfLocked) {
9831            int[] types = new int[pids.length];
9832            int worstType = 0;
9833            for (int i=0; i<pids.length; i++) {
9834                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9835                if (proc != null) {
9836                    int type = proc.setAdj;
9837                    types[i] = type;
9838                    if (type > worstType) {
9839                        worstType = type;
9840                    }
9841                }
9842            }
9843
9844            // If the worst oom_adj is somewhere in the cached proc LRU range,
9845            // then constrain it so we will kill all cached procs.
9846            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9847                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9848                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9849            }
9850
9851            // If this is not a secure call, don't let it kill processes that
9852            // are important.
9853            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9854                worstType = ProcessList.SERVICE_ADJ;
9855            }
9856
9857            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9858            for (int i=0; i<pids.length; i++) {
9859                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9860                if (proc == null) {
9861                    continue;
9862                }
9863                int adj = proc.setAdj;
9864                if (adj >= worstType && !proc.killedByAm) {
9865                    killUnneededProcessLocked(proc, reason);
9866                    killed = true;
9867                }
9868            }
9869        }
9870        return killed;
9871    }
9872
9873    @Override
9874    public void killUid(int uid, String reason) {
9875        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9876            throw new SecurityException("killUid only available to the system");
9877        }
9878        synchronized (this) {
9879            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9880                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9881                    reason != null ? reason : "kill uid");
9882        }
9883    }
9884
9885    @Override
9886    public boolean killProcessesBelowForeground(String reason) {
9887        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9888            throw new SecurityException("killProcessesBelowForeground() only available to system");
9889        }
9890
9891        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9892    }
9893
9894    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9895        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9896            throw new SecurityException("killProcessesBelowAdj() only available to system");
9897        }
9898
9899        boolean killed = false;
9900        synchronized (mPidsSelfLocked) {
9901            final int size = mPidsSelfLocked.size();
9902            for (int i = 0; i < size; i++) {
9903                final int pid = mPidsSelfLocked.keyAt(i);
9904                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9905                if (proc == null) continue;
9906
9907                final int adj = proc.setAdj;
9908                if (adj > belowAdj && !proc.killedByAm) {
9909                    killUnneededProcessLocked(proc, reason);
9910                    killed = true;
9911                }
9912            }
9913        }
9914        return killed;
9915    }
9916
9917    @Override
9918    public void hang(final IBinder who, boolean allowRestart) {
9919        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9920                != PackageManager.PERMISSION_GRANTED) {
9921            throw new SecurityException("Requires permission "
9922                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9923        }
9924
9925        final IBinder.DeathRecipient death = new DeathRecipient() {
9926            @Override
9927            public void binderDied() {
9928                synchronized (this) {
9929                    notifyAll();
9930                }
9931            }
9932        };
9933
9934        try {
9935            who.linkToDeath(death, 0);
9936        } catch (RemoteException e) {
9937            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9938            return;
9939        }
9940
9941        synchronized (this) {
9942            Watchdog.getInstance().setAllowRestart(allowRestart);
9943            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9944            synchronized (death) {
9945                while (who.isBinderAlive()) {
9946                    try {
9947                        death.wait();
9948                    } catch (InterruptedException e) {
9949                    }
9950                }
9951            }
9952            Watchdog.getInstance().setAllowRestart(true);
9953        }
9954    }
9955
9956    @Override
9957    public void restart() {
9958        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9959                != PackageManager.PERMISSION_GRANTED) {
9960            throw new SecurityException("Requires permission "
9961                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9962        }
9963
9964        Log.i(TAG, "Sending shutdown broadcast...");
9965
9966        BroadcastReceiver br = new BroadcastReceiver() {
9967            @Override public void onReceive(Context context, Intent intent) {
9968                // Now the broadcast is done, finish up the low-level shutdown.
9969                Log.i(TAG, "Shutting down activity manager...");
9970                shutdown(10000);
9971                Log.i(TAG, "Shutdown complete, restarting!");
9972                Process.killProcess(Process.myPid());
9973                System.exit(10);
9974            }
9975        };
9976
9977        // First send the high-level shut down broadcast.
9978        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9979        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9980        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9981        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9982        mContext.sendOrderedBroadcastAsUser(intent,
9983                UserHandle.ALL, null, br, mHandler, 0, null, null);
9984        */
9985        br.onReceive(mContext, intent);
9986    }
9987
9988    private long getLowRamTimeSinceIdle(long now) {
9989        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9990    }
9991
9992    @Override
9993    public void performIdleMaintenance() {
9994        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9995                != PackageManager.PERMISSION_GRANTED) {
9996            throw new SecurityException("Requires permission "
9997                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9998        }
9999
10000        synchronized (this) {
10001            final long now = SystemClock.uptimeMillis();
10002            final long timeSinceLastIdle = now - mLastIdleTime;
10003            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10004            mLastIdleTime = now;
10005            mLowRamTimeSinceLastIdle = 0;
10006            if (mLowRamStartTime != 0) {
10007                mLowRamStartTime = now;
10008            }
10009
10010            StringBuilder sb = new StringBuilder(128);
10011            sb.append("Idle maintenance over ");
10012            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10013            sb.append(" low RAM for ");
10014            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10015            Slog.i(TAG, sb.toString());
10016
10017            // If at least 1/3 of our time since the last idle period has been spent
10018            // with RAM low, then we want to kill processes.
10019            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10020
10021            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10022                ProcessRecord proc = mLruProcesses.get(i);
10023                if (proc.notCachedSinceIdle) {
10024                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10025                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10026                        if (doKilling && proc.initialIdlePss != 0
10027                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10028                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
10029                                    + " from " + proc.initialIdlePss + ")");
10030                        }
10031                    }
10032                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10033                    proc.notCachedSinceIdle = true;
10034                    proc.initialIdlePss = 0;
10035                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10036                            isSleeping(), now);
10037                }
10038            }
10039
10040            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10041            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10042        }
10043    }
10044
10045    private void retrieveSettings() {
10046        final ContentResolver resolver = mContext.getContentResolver();
10047        String debugApp = Settings.Global.getString(
10048            resolver, Settings.Global.DEBUG_APP);
10049        boolean waitForDebugger = Settings.Global.getInt(
10050            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10051        boolean alwaysFinishActivities = Settings.Global.getInt(
10052            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10053        boolean forceRtl = Settings.Global.getInt(
10054                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10055        // Transfer any global setting for forcing RTL layout, into a System Property
10056        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10057
10058        Configuration configuration = new Configuration();
10059        Settings.System.getConfiguration(resolver, configuration);
10060        if (forceRtl) {
10061            // This will take care of setting the correct layout direction flags
10062            configuration.setLayoutDirection(configuration.locale);
10063        }
10064
10065        synchronized (this) {
10066            mDebugApp = mOrigDebugApp = debugApp;
10067            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10068            mAlwaysFinishActivities = alwaysFinishActivities;
10069            // This happens before any activities are started, so we can
10070            // change mConfiguration in-place.
10071            updateConfigurationLocked(configuration, null, false, true);
10072            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10073        }
10074    }
10075
10076    public boolean testIsSystemReady() {
10077        // no need to synchronize(this) just to read & return the value
10078        return mSystemReady;
10079    }
10080
10081    private static File getCalledPreBootReceiversFile() {
10082        File dataDir = Environment.getDataDirectory();
10083        File systemDir = new File(dataDir, "system");
10084        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10085        return fname;
10086    }
10087
10088    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10089        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10090        File file = getCalledPreBootReceiversFile();
10091        FileInputStream fis = null;
10092        try {
10093            fis = new FileInputStream(file);
10094            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10095            int fvers = dis.readInt();
10096            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10097                String vers = dis.readUTF();
10098                String codename = dis.readUTF();
10099                String build = dis.readUTF();
10100                if (android.os.Build.VERSION.RELEASE.equals(vers)
10101                        && android.os.Build.VERSION.CODENAME.equals(codename)
10102                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10103                    int num = dis.readInt();
10104                    while (num > 0) {
10105                        num--;
10106                        String pkg = dis.readUTF();
10107                        String cls = dis.readUTF();
10108                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10109                    }
10110                }
10111            }
10112        } catch (FileNotFoundException e) {
10113        } catch (IOException e) {
10114            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10115        } finally {
10116            if (fis != null) {
10117                try {
10118                    fis.close();
10119                } catch (IOException e) {
10120                }
10121            }
10122        }
10123        return lastDoneReceivers;
10124    }
10125
10126    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10127        File file = getCalledPreBootReceiversFile();
10128        FileOutputStream fos = null;
10129        DataOutputStream dos = null;
10130        try {
10131            fos = new FileOutputStream(file);
10132            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10133            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10134            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10135            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10136            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10137            dos.writeInt(list.size());
10138            for (int i=0; i<list.size(); i++) {
10139                dos.writeUTF(list.get(i).getPackageName());
10140                dos.writeUTF(list.get(i).getClassName());
10141            }
10142        } catch (IOException e) {
10143            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10144            file.delete();
10145        } finally {
10146            FileUtils.sync(fos);
10147            if (dos != null) {
10148                try {
10149                    dos.close();
10150                } catch (IOException e) {
10151                    // TODO Auto-generated catch block
10152                    e.printStackTrace();
10153                }
10154            }
10155        }
10156    }
10157
10158    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10159            ArrayList<ComponentName> doneReceivers, int userId) {
10160        boolean waitingUpdate = false;
10161        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10162        List<ResolveInfo> ris = null;
10163        try {
10164            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10165                    intent, null, 0, userId);
10166        } catch (RemoteException e) {
10167        }
10168        if (ris != null) {
10169            for (int i=ris.size()-1; i>=0; i--) {
10170                if ((ris.get(i).activityInfo.applicationInfo.flags
10171                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10172                    ris.remove(i);
10173                }
10174            }
10175            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10176
10177            // For User 0, load the version number. When delivering to a new user, deliver
10178            // to all receivers.
10179            if (userId == UserHandle.USER_OWNER) {
10180                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10181                for (int i=0; i<ris.size(); i++) {
10182                    ActivityInfo ai = ris.get(i).activityInfo;
10183                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10184                    if (lastDoneReceivers.contains(comp)) {
10185                        // We already did the pre boot receiver for this app with the current
10186                        // platform version, so don't do it again...
10187                        ris.remove(i);
10188                        i--;
10189                        // ...however, do keep it as one that has been done, so we don't
10190                        // forget about it when rewriting the file of last done receivers.
10191                        doneReceivers.add(comp);
10192                    }
10193                }
10194            }
10195
10196            // If primary user, send broadcast to all available users, else just to userId
10197            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10198                    : new int[] { userId };
10199            for (int i = 0; i < ris.size(); i++) {
10200                ActivityInfo ai = ris.get(i).activityInfo;
10201                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10202                doneReceivers.add(comp);
10203                intent.setComponent(comp);
10204                for (int j=0; j<users.length; j++) {
10205                    IIntentReceiver finisher = null;
10206                    // On last receiver and user, set up a completion callback
10207                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10208                        finisher = new IIntentReceiver.Stub() {
10209                            public void performReceive(Intent intent, int resultCode,
10210                                    String data, Bundle extras, boolean ordered,
10211                                    boolean sticky, int sendingUser) {
10212                                // The raw IIntentReceiver interface is called
10213                                // with the AM lock held, so redispatch to
10214                                // execute our code without the lock.
10215                                mHandler.post(onFinishCallback);
10216                            }
10217                        };
10218                    }
10219                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10220                            + " for user " + users[j]);
10221                    broadcastIntentLocked(null, null, intent, null, finisher,
10222                            0, null, null, null, AppOpsManager.OP_NONE,
10223                            true, false, MY_PID, Process.SYSTEM_UID,
10224                            users[j]);
10225                    if (finisher != null) {
10226                        waitingUpdate = true;
10227                    }
10228                }
10229            }
10230        }
10231
10232        return waitingUpdate;
10233    }
10234
10235    public void systemReady(final Runnable goingCallback) {
10236        synchronized(this) {
10237            if (mSystemReady) {
10238                // If we're done calling all the receivers, run the next "boot phase" passed in
10239                // by the SystemServer
10240                if (goingCallback != null) {
10241                    goingCallback.run();
10242                }
10243                return;
10244            }
10245
10246            // Make sure we have the current profile info, since it is needed for
10247            // security checks.
10248            updateCurrentProfileIdsLocked();
10249
10250            if (mRecentTasks == null) {
10251                mRecentTasks = mTaskPersister.restoreTasksLocked();
10252                if (!mRecentTasks.isEmpty()) {
10253                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10254                }
10255                mTaskPersister.startPersisting();
10256            }
10257
10258            // Check to see if there are any update receivers to run.
10259            if (!mDidUpdate) {
10260                if (mWaitingUpdate) {
10261                    return;
10262                }
10263                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10264                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10265                    public void run() {
10266                        synchronized (ActivityManagerService.this) {
10267                            mDidUpdate = true;
10268                        }
10269                        writeLastDonePreBootReceivers(doneReceivers);
10270                        showBootMessage(mContext.getText(
10271                                R.string.android_upgrading_complete),
10272                                false);
10273                        systemReady(goingCallback);
10274                    }
10275                }, doneReceivers, UserHandle.USER_OWNER);
10276
10277                if (mWaitingUpdate) {
10278                    return;
10279                }
10280                mDidUpdate = true;
10281            }
10282
10283            mAppOpsService.systemReady();
10284            mSystemReady = true;
10285        }
10286
10287        ArrayList<ProcessRecord> procsToKill = null;
10288        synchronized(mPidsSelfLocked) {
10289            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10290                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10291                if (!isAllowedWhileBooting(proc.info)){
10292                    if (procsToKill == null) {
10293                        procsToKill = new ArrayList<ProcessRecord>();
10294                    }
10295                    procsToKill.add(proc);
10296                }
10297            }
10298        }
10299
10300        synchronized(this) {
10301            if (procsToKill != null) {
10302                for (int i=procsToKill.size()-1; i>=0; i--) {
10303                    ProcessRecord proc = procsToKill.get(i);
10304                    Slog.i(TAG, "Removing system update proc: " + proc);
10305                    removeProcessLocked(proc, true, false, "system update done");
10306                }
10307            }
10308
10309            // Now that we have cleaned up any update processes, we
10310            // are ready to start launching real processes and know that
10311            // we won't trample on them any more.
10312            mProcessesReady = true;
10313        }
10314
10315        Slog.i(TAG, "System now ready");
10316        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10317            SystemClock.uptimeMillis());
10318
10319        synchronized(this) {
10320            // Make sure we have no pre-ready processes sitting around.
10321
10322            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10323                ResolveInfo ri = mContext.getPackageManager()
10324                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10325                                STOCK_PM_FLAGS);
10326                CharSequence errorMsg = null;
10327                if (ri != null) {
10328                    ActivityInfo ai = ri.activityInfo;
10329                    ApplicationInfo app = ai.applicationInfo;
10330                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10331                        mTopAction = Intent.ACTION_FACTORY_TEST;
10332                        mTopData = null;
10333                        mTopComponent = new ComponentName(app.packageName,
10334                                ai.name);
10335                    } else {
10336                        errorMsg = mContext.getResources().getText(
10337                                com.android.internal.R.string.factorytest_not_system);
10338                    }
10339                } else {
10340                    errorMsg = mContext.getResources().getText(
10341                            com.android.internal.R.string.factorytest_no_action);
10342                }
10343                if (errorMsg != null) {
10344                    mTopAction = null;
10345                    mTopData = null;
10346                    mTopComponent = null;
10347                    Message msg = Message.obtain();
10348                    msg.what = SHOW_FACTORY_ERROR_MSG;
10349                    msg.getData().putCharSequence("msg", errorMsg);
10350                    mHandler.sendMessage(msg);
10351                }
10352            }
10353        }
10354
10355        retrieveSettings();
10356
10357        synchronized (this) {
10358            readGrantedUriPermissionsLocked();
10359        }
10360
10361        if (goingCallback != null) goingCallback.run();
10362
10363        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10364                Integer.toString(mCurrentUserId), mCurrentUserId);
10365        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10366                Integer.toString(mCurrentUserId), mCurrentUserId);
10367        mSystemServiceManager.startUser(mCurrentUserId);
10368
10369        synchronized (this) {
10370            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10371                try {
10372                    List apps = AppGlobals.getPackageManager().
10373                        getPersistentApplications(STOCK_PM_FLAGS);
10374                    if (apps != null) {
10375                        int N = apps.size();
10376                        int i;
10377                        for (i=0; i<N; i++) {
10378                            ApplicationInfo info
10379                                = (ApplicationInfo)apps.get(i);
10380                            if (info != null &&
10381                                    !info.packageName.equals("android")) {
10382                                addAppLocked(info, false, null /* ABI override */);
10383                            }
10384                        }
10385                    }
10386                } catch (RemoteException ex) {
10387                    // pm is in same process, this will never happen.
10388                }
10389            }
10390
10391            // Start up initial activity.
10392            mBooting = true;
10393
10394            try {
10395                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10396                    Message msg = Message.obtain();
10397                    msg.what = SHOW_UID_ERROR_MSG;
10398                    mHandler.sendMessage(msg);
10399                }
10400            } catch (RemoteException e) {
10401            }
10402
10403            long ident = Binder.clearCallingIdentity();
10404            try {
10405                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10406                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10407                        | Intent.FLAG_RECEIVER_FOREGROUND);
10408                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10409                broadcastIntentLocked(null, null, intent,
10410                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10411                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10412                intent = new Intent(Intent.ACTION_USER_STARTING);
10413                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10414                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10415                broadcastIntentLocked(null, null, intent,
10416                        null, new IIntentReceiver.Stub() {
10417                            @Override
10418                            public void performReceive(Intent intent, int resultCode, String data,
10419                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10420                                    throws RemoteException {
10421                            }
10422                        }, 0, null, null,
10423                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10424                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10425            } catch (Throwable t) {
10426                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10427            } finally {
10428                Binder.restoreCallingIdentity(ident);
10429            }
10430            mStackSupervisor.resumeTopActivitiesLocked();
10431            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10432        }
10433    }
10434
10435    private boolean makeAppCrashingLocked(ProcessRecord app,
10436            String shortMsg, String longMsg, String stackTrace) {
10437        app.crashing = true;
10438        app.crashingReport = generateProcessError(app,
10439                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10440        startAppProblemLocked(app);
10441        app.stopFreezingAllLocked();
10442        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10443    }
10444
10445    private void makeAppNotRespondingLocked(ProcessRecord app,
10446            String activity, String shortMsg, String longMsg) {
10447        app.notResponding = true;
10448        app.notRespondingReport = generateProcessError(app,
10449                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10450                activity, shortMsg, longMsg, null);
10451        startAppProblemLocked(app);
10452        app.stopFreezingAllLocked();
10453    }
10454
10455    /**
10456     * Generate a process error record, suitable for attachment to a ProcessRecord.
10457     *
10458     * @param app The ProcessRecord in which the error occurred.
10459     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10460     *                      ActivityManager.AppErrorStateInfo
10461     * @param activity The activity associated with the crash, if known.
10462     * @param shortMsg Short message describing the crash.
10463     * @param longMsg Long message describing the crash.
10464     * @param stackTrace Full crash stack trace, may be null.
10465     *
10466     * @return Returns a fully-formed AppErrorStateInfo record.
10467     */
10468    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10469            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10470        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10471
10472        report.condition = condition;
10473        report.processName = app.processName;
10474        report.pid = app.pid;
10475        report.uid = app.info.uid;
10476        report.tag = activity;
10477        report.shortMsg = shortMsg;
10478        report.longMsg = longMsg;
10479        report.stackTrace = stackTrace;
10480
10481        return report;
10482    }
10483
10484    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10485        synchronized (this) {
10486            app.crashing = false;
10487            app.crashingReport = null;
10488            app.notResponding = false;
10489            app.notRespondingReport = null;
10490            if (app.anrDialog == fromDialog) {
10491                app.anrDialog = null;
10492            }
10493            if (app.waitDialog == fromDialog) {
10494                app.waitDialog = null;
10495            }
10496            if (app.pid > 0 && app.pid != MY_PID) {
10497                handleAppCrashLocked(app, null, null, null);
10498                killUnneededProcessLocked(app, "user request after error");
10499            }
10500        }
10501    }
10502
10503    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10504            String stackTrace) {
10505        long now = SystemClock.uptimeMillis();
10506
10507        Long crashTime;
10508        if (!app.isolated) {
10509            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10510        } else {
10511            crashTime = null;
10512        }
10513        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10514            // This process loses!
10515            Slog.w(TAG, "Process " + app.info.processName
10516                    + " has crashed too many times: killing!");
10517            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10518                    app.userId, app.info.processName, app.uid);
10519            mStackSupervisor.handleAppCrashLocked(app);
10520            if (!app.persistent) {
10521                // We don't want to start this process again until the user
10522                // explicitly does so...  but for persistent process, we really
10523                // need to keep it running.  If a persistent process is actually
10524                // repeatedly crashing, then badness for everyone.
10525                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10526                        app.info.processName);
10527                if (!app.isolated) {
10528                    // XXX We don't have a way to mark isolated processes
10529                    // as bad, since they don't have a peristent identity.
10530                    mBadProcesses.put(app.info.processName, app.uid,
10531                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10532                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10533                }
10534                app.bad = true;
10535                app.removed = true;
10536                // Don't let services in this process be restarted and potentially
10537                // annoy the user repeatedly.  Unless it is persistent, since those
10538                // processes run critical code.
10539                removeProcessLocked(app, false, false, "crash");
10540                mStackSupervisor.resumeTopActivitiesLocked();
10541                return false;
10542            }
10543            mStackSupervisor.resumeTopActivitiesLocked();
10544        } else {
10545            mStackSupervisor.finishTopRunningActivityLocked(app);
10546        }
10547
10548        // Bump up the crash count of any services currently running in the proc.
10549        for (int i=app.services.size()-1; i>=0; i--) {
10550            // Any services running in the application need to be placed
10551            // back in the pending list.
10552            ServiceRecord sr = app.services.valueAt(i);
10553            sr.crashCount++;
10554        }
10555
10556        // If the crashing process is what we consider to be the "home process" and it has been
10557        // replaced by a third-party app, clear the package preferred activities from packages
10558        // with a home activity running in the process to prevent a repeatedly crashing app
10559        // from blocking the user to manually clear the list.
10560        final ArrayList<ActivityRecord> activities = app.activities;
10561        if (app == mHomeProcess && activities.size() > 0
10562                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10563            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10564                final ActivityRecord r = activities.get(activityNdx);
10565                if (r.isHomeActivity()) {
10566                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10567                    try {
10568                        ActivityThread.getPackageManager()
10569                                .clearPackagePreferredActivities(r.packageName);
10570                    } catch (RemoteException c) {
10571                        // pm is in same process, this will never happen.
10572                    }
10573                }
10574            }
10575        }
10576
10577        if (!app.isolated) {
10578            // XXX Can't keep track of crash times for isolated processes,
10579            // because they don't have a perisistent identity.
10580            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10581        }
10582
10583        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10584        return true;
10585    }
10586
10587    void startAppProblemLocked(ProcessRecord app) {
10588        // If this app is not running under the current user, then we
10589        // can't give it a report button because that would require
10590        // launching the report UI under a different user.
10591        app.errorReportReceiver = null;
10592
10593        for (int userId : mCurrentProfileIds) {
10594            if (app.userId == userId) {
10595                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10596                        mContext, app.info.packageName, app.info.flags);
10597            }
10598        }
10599        skipCurrentReceiverLocked(app);
10600    }
10601
10602    void skipCurrentReceiverLocked(ProcessRecord app) {
10603        for (BroadcastQueue queue : mBroadcastQueues) {
10604            queue.skipCurrentReceiverLocked(app);
10605        }
10606    }
10607
10608    /**
10609     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10610     * The application process will exit immediately after this call returns.
10611     * @param app object of the crashing app, null for the system server
10612     * @param crashInfo describing the exception
10613     */
10614    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10615        ProcessRecord r = findAppProcess(app, "Crash");
10616        final String processName = app == null ? "system_server"
10617                : (r == null ? "unknown" : r.processName);
10618
10619        handleApplicationCrashInner("crash", r, processName, crashInfo);
10620    }
10621
10622    /* Native crash reporting uses this inner version because it needs to be somewhat
10623     * decoupled from the AM-managed cleanup lifecycle
10624     */
10625    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10626            ApplicationErrorReport.CrashInfo crashInfo) {
10627        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10628                UserHandle.getUserId(Binder.getCallingUid()), processName,
10629                r == null ? -1 : r.info.flags,
10630                crashInfo.exceptionClassName,
10631                crashInfo.exceptionMessage,
10632                crashInfo.throwFileName,
10633                crashInfo.throwLineNumber);
10634
10635        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10636
10637        crashApplication(r, crashInfo);
10638    }
10639
10640    public void handleApplicationStrictModeViolation(
10641            IBinder app,
10642            int violationMask,
10643            StrictMode.ViolationInfo info) {
10644        ProcessRecord r = findAppProcess(app, "StrictMode");
10645        if (r == null) {
10646            return;
10647        }
10648
10649        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10650            Integer stackFingerprint = info.hashCode();
10651            boolean logIt = true;
10652            synchronized (mAlreadyLoggedViolatedStacks) {
10653                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10654                    logIt = false;
10655                    // TODO: sub-sample into EventLog for these, with
10656                    // the info.durationMillis?  Then we'd get
10657                    // the relative pain numbers, without logging all
10658                    // the stack traces repeatedly.  We'd want to do
10659                    // likewise in the client code, which also does
10660                    // dup suppression, before the Binder call.
10661                } else {
10662                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10663                        mAlreadyLoggedViolatedStacks.clear();
10664                    }
10665                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10666                }
10667            }
10668            if (logIt) {
10669                logStrictModeViolationToDropBox(r, info);
10670            }
10671        }
10672
10673        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10674            AppErrorResult result = new AppErrorResult();
10675            synchronized (this) {
10676                final long origId = Binder.clearCallingIdentity();
10677
10678                Message msg = Message.obtain();
10679                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10680                HashMap<String, Object> data = new HashMap<String, Object>();
10681                data.put("result", result);
10682                data.put("app", r);
10683                data.put("violationMask", violationMask);
10684                data.put("info", info);
10685                msg.obj = data;
10686                mHandler.sendMessage(msg);
10687
10688                Binder.restoreCallingIdentity(origId);
10689            }
10690            int res = result.get();
10691            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10692        }
10693    }
10694
10695    // Depending on the policy in effect, there could be a bunch of
10696    // these in quick succession so we try to batch these together to
10697    // minimize disk writes, number of dropbox entries, and maximize
10698    // compression, by having more fewer, larger records.
10699    private void logStrictModeViolationToDropBox(
10700            ProcessRecord process,
10701            StrictMode.ViolationInfo info) {
10702        if (info == null) {
10703            return;
10704        }
10705        final boolean isSystemApp = process == null ||
10706                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10707                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10708        final String processName = process == null ? "unknown" : process.processName;
10709        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10710        final DropBoxManager dbox = (DropBoxManager)
10711                mContext.getSystemService(Context.DROPBOX_SERVICE);
10712
10713        // Exit early if the dropbox isn't configured to accept this report type.
10714        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10715
10716        boolean bufferWasEmpty;
10717        boolean needsFlush;
10718        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10719        synchronized (sb) {
10720            bufferWasEmpty = sb.length() == 0;
10721            appendDropBoxProcessHeaders(process, processName, sb);
10722            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10723            sb.append("System-App: ").append(isSystemApp).append("\n");
10724            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10725            if (info.violationNumThisLoop != 0) {
10726                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10727            }
10728            if (info.numAnimationsRunning != 0) {
10729                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10730            }
10731            if (info.broadcastIntentAction != null) {
10732                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10733            }
10734            if (info.durationMillis != -1) {
10735                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10736            }
10737            if (info.numInstances != -1) {
10738                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10739            }
10740            if (info.tags != null) {
10741                for (String tag : info.tags) {
10742                    sb.append("Span-Tag: ").append(tag).append("\n");
10743                }
10744            }
10745            sb.append("\n");
10746            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10747                sb.append(info.crashInfo.stackTrace);
10748            }
10749            sb.append("\n");
10750
10751            // Only buffer up to ~64k.  Various logging bits truncate
10752            // things at 128k.
10753            needsFlush = (sb.length() > 64 * 1024);
10754        }
10755
10756        // Flush immediately if the buffer's grown too large, or this
10757        // is a non-system app.  Non-system apps are isolated with a
10758        // different tag & policy and not batched.
10759        //
10760        // Batching is useful during internal testing with
10761        // StrictMode settings turned up high.  Without batching,
10762        // thousands of separate files could be created on boot.
10763        if (!isSystemApp || needsFlush) {
10764            new Thread("Error dump: " + dropboxTag) {
10765                @Override
10766                public void run() {
10767                    String report;
10768                    synchronized (sb) {
10769                        report = sb.toString();
10770                        sb.delete(0, sb.length());
10771                        sb.trimToSize();
10772                    }
10773                    if (report.length() != 0) {
10774                        dbox.addText(dropboxTag, report);
10775                    }
10776                }
10777            }.start();
10778            return;
10779        }
10780
10781        // System app batching:
10782        if (!bufferWasEmpty) {
10783            // An existing dropbox-writing thread is outstanding, so
10784            // we don't need to start it up.  The existing thread will
10785            // catch the buffer appends we just did.
10786            return;
10787        }
10788
10789        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10790        // (After this point, we shouldn't access AMS internal data structures.)
10791        new Thread("Error dump: " + dropboxTag) {
10792            @Override
10793            public void run() {
10794                // 5 second sleep to let stacks arrive and be batched together
10795                try {
10796                    Thread.sleep(5000);  // 5 seconds
10797                } catch (InterruptedException e) {}
10798
10799                String errorReport;
10800                synchronized (mStrictModeBuffer) {
10801                    errorReport = mStrictModeBuffer.toString();
10802                    if (errorReport.length() == 0) {
10803                        return;
10804                    }
10805                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10806                    mStrictModeBuffer.trimToSize();
10807                }
10808                dbox.addText(dropboxTag, errorReport);
10809            }
10810        }.start();
10811    }
10812
10813    /**
10814     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10815     * @param app object of the crashing app, null for the system server
10816     * @param tag reported by the caller
10817     * @param crashInfo describing the context of the error
10818     * @return true if the process should exit immediately (WTF is fatal)
10819     */
10820    public boolean handleApplicationWtf(IBinder app, String tag,
10821            ApplicationErrorReport.CrashInfo crashInfo) {
10822        ProcessRecord r = findAppProcess(app, "WTF");
10823        final String processName = app == null ? "system_server"
10824                : (r == null ? "unknown" : r.processName);
10825
10826        EventLog.writeEvent(EventLogTags.AM_WTF,
10827                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10828                processName,
10829                r == null ? -1 : r.info.flags,
10830                tag, crashInfo.exceptionMessage);
10831
10832        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10833
10834        if (r != null && r.pid != Process.myPid() &&
10835                Settings.Global.getInt(mContext.getContentResolver(),
10836                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10837            crashApplication(r, crashInfo);
10838            return true;
10839        } else {
10840            return false;
10841        }
10842    }
10843
10844    /**
10845     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10846     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10847     */
10848    private ProcessRecord findAppProcess(IBinder app, String reason) {
10849        if (app == null) {
10850            return null;
10851        }
10852
10853        synchronized (this) {
10854            final int NP = mProcessNames.getMap().size();
10855            for (int ip=0; ip<NP; ip++) {
10856                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10857                final int NA = apps.size();
10858                for (int ia=0; ia<NA; ia++) {
10859                    ProcessRecord p = apps.valueAt(ia);
10860                    if (p.thread != null && p.thread.asBinder() == app) {
10861                        return p;
10862                    }
10863                }
10864            }
10865
10866            Slog.w(TAG, "Can't find mystery application for " + reason
10867                    + " from pid=" + Binder.getCallingPid()
10868                    + " uid=" + Binder.getCallingUid() + ": " + app);
10869            return null;
10870        }
10871    }
10872
10873    /**
10874     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10875     * to append various headers to the dropbox log text.
10876     */
10877    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10878            StringBuilder sb) {
10879        // Watchdog thread ends up invoking this function (with
10880        // a null ProcessRecord) to add the stack file to dropbox.
10881        // Do not acquire a lock on this (am) in such cases, as it
10882        // could cause a potential deadlock, if and when watchdog
10883        // is invoked due to unavailability of lock on am and it
10884        // would prevent watchdog from killing system_server.
10885        if (process == null) {
10886            sb.append("Process: ").append(processName).append("\n");
10887            return;
10888        }
10889        // Note: ProcessRecord 'process' is guarded by the service
10890        // instance.  (notably process.pkgList, which could otherwise change
10891        // concurrently during execution of this method)
10892        synchronized (this) {
10893            sb.append("Process: ").append(processName).append("\n");
10894            int flags = process.info.flags;
10895            IPackageManager pm = AppGlobals.getPackageManager();
10896            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10897            for (int ip=0; ip<process.pkgList.size(); ip++) {
10898                String pkg = process.pkgList.keyAt(ip);
10899                sb.append("Package: ").append(pkg);
10900                try {
10901                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10902                    if (pi != null) {
10903                        sb.append(" v").append(pi.versionCode);
10904                        if (pi.versionName != null) {
10905                            sb.append(" (").append(pi.versionName).append(")");
10906                        }
10907                    }
10908                } catch (RemoteException e) {
10909                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10910                }
10911                sb.append("\n");
10912            }
10913        }
10914    }
10915
10916    private static String processClass(ProcessRecord process) {
10917        if (process == null || process.pid == MY_PID) {
10918            return "system_server";
10919        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10920            return "system_app";
10921        } else {
10922            return "data_app";
10923        }
10924    }
10925
10926    /**
10927     * Write a description of an error (crash, WTF, ANR) to the drop box.
10928     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10929     * @param process which caused the error, null means the system server
10930     * @param activity which triggered the error, null if unknown
10931     * @param parent activity related to the error, null if unknown
10932     * @param subject line related to the error, null if absent
10933     * @param report in long form describing the error, null if absent
10934     * @param logFile to include in the report, null if none
10935     * @param crashInfo giving an application stack trace, null if absent
10936     */
10937    public void addErrorToDropBox(String eventType,
10938            ProcessRecord process, String processName, ActivityRecord activity,
10939            ActivityRecord parent, String subject,
10940            final String report, final File logFile,
10941            final ApplicationErrorReport.CrashInfo crashInfo) {
10942        // NOTE -- this must never acquire the ActivityManagerService lock,
10943        // otherwise the watchdog may be prevented from resetting the system.
10944
10945        final String dropboxTag = processClass(process) + "_" + eventType;
10946        final DropBoxManager dbox = (DropBoxManager)
10947                mContext.getSystemService(Context.DROPBOX_SERVICE);
10948
10949        // Exit early if the dropbox isn't configured to accept this report type.
10950        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10951
10952        final StringBuilder sb = new StringBuilder(1024);
10953        appendDropBoxProcessHeaders(process, processName, sb);
10954        if (activity != null) {
10955            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10956        }
10957        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10958            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10959        }
10960        if (parent != null && parent != activity) {
10961            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10962        }
10963        if (subject != null) {
10964            sb.append("Subject: ").append(subject).append("\n");
10965        }
10966        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10967        if (Debug.isDebuggerConnected()) {
10968            sb.append("Debugger: Connected\n");
10969        }
10970        sb.append("\n");
10971
10972        // Do the rest in a worker thread to avoid blocking the caller on I/O
10973        // (After this point, we shouldn't access AMS internal data structures.)
10974        Thread worker = new Thread("Error dump: " + dropboxTag) {
10975            @Override
10976            public void run() {
10977                if (report != null) {
10978                    sb.append(report);
10979                }
10980                if (logFile != null) {
10981                    try {
10982                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10983                                    "\n\n[[TRUNCATED]]"));
10984                    } catch (IOException e) {
10985                        Slog.e(TAG, "Error reading " + logFile, e);
10986                    }
10987                }
10988                if (crashInfo != null && crashInfo.stackTrace != null) {
10989                    sb.append(crashInfo.stackTrace);
10990                }
10991
10992                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10993                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10994                if (lines > 0) {
10995                    sb.append("\n");
10996
10997                    // Merge several logcat streams, and take the last N lines
10998                    InputStreamReader input = null;
10999                    try {
11000                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11001                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11002                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11003
11004                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11005                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11006                        input = new InputStreamReader(logcat.getInputStream());
11007
11008                        int num;
11009                        char[] buf = new char[8192];
11010                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11011                    } catch (IOException e) {
11012                        Slog.e(TAG, "Error running logcat", e);
11013                    } finally {
11014                        if (input != null) try { input.close(); } catch (IOException e) {}
11015                    }
11016                }
11017
11018                dbox.addText(dropboxTag, sb.toString());
11019            }
11020        };
11021
11022        if (process == null) {
11023            // If process is null, we are being called from some internal code
11024            // and may be about to die -- run this synchronously.
11025            worker.run();
11026        } else {
11027            worker.start();
11028        }
11029    }
11030
11031    /**
11032     * Bring up the "unexpected error" dialog box for a crashing app.
11033     * Deal with edge cases (intercepts from instrumented applications,
11034     * ActivityController, error intent receivers, that sort of thing).
11035     * @param r the application crashing
11036     * @param crashInfo describing the failure
11037     */
11038    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11039        long timeMillis = System.currentTimeMillis();
11040        String shortMsg = crashInfo.exceptionClassName;
11041        String longMsg = crashInfo.exceptionMessage;
11042        String stackTrace = crashInfo.stackTrace;
11043        if (shortMsg != null && longMsg != null) {
11044            longMsg = shortMsg + ": " + longMsg;
11045        } else if (shortMsg != null) {
11046            longMsg = shortMsg;
11047        }
11048
11049        AppErrorResult result = new AppErrorResult();
11050        synchronized (this) {
11051            if (mController != null) {
11052                try {
11053                    String name = r != null ? r.processName : null;
11054                    int pid = r != null ? r.pid : Binder.getCallingPid();
11055                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11056                    if (!mController.appCrashed(name, pid,
11057                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11058                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11059                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11060                            Slog.w(TAG, "Skip killing native crashed app " + name
11061                                    + "(" + pid + ") during testing");
11062                        } else {
11063                            Slog.w(TAG, "Force-killing crashed app " + name
11064                                    + " at watcher's request");
11065                            Process.killProcess(pid);
11066                            if (r != null) {
11067                                Process.killProcessGroup(uid, pid);
11068                            }
11069                        }
11070                        return;
11071                    }
11072                } catch (RemoteException e) {
11073                    mController = null;
11074                    Watchdog.getInstance().setActivityController(null);
11075                }
11076            }
11077
11078            final long origId = Binder.clearCallingIdentity();
11079
11080            // If this process is running instrumentation, finish it.
11081            if (r != null && r.instrumentationClass != null) {
11082                Slog.w(TAG, "Error in app " + r.processName
11083                      + " running instrumentation " + r.instrumentationClass + ":");
11084                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11085                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11086                Bundle info = new Bundle();
11087                info.putString("shortMsg", shortMsg);
11088                info.putString("longMsg", longMsg);
11089                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11090                Binder.restoreCallingIdentity(origId);
11091                return;
11092            }
11093
11094            // If we can't identify the process or it's already exceeded its crash quota,
11095            // quit right away without showing a crash dialog.
11096            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11097                Binder.restoreCallingIdentity(origId);
11098                return;
11099            }
11100
11101            Message msg = Message.obtain();
11102            msg.what = SHOW_ERROR_MSG;
11103            HashMap data = new HashMap();
11104            data.put("result", result);
11105            data.put("app", r);
11106            msg.obj = data;
11107            mHandler.sendMessage(msg);
11108
11109            Binder.restoreCallingIdentity(origId);
11110        }
11111
11112        int res = result.get();
11113
11114        Intent appErrorIntent = null;
11115        synchronized (this) {
11116            if (r != null && !r.isolated) {
11117                // XXX Can't keep track of crash time for isolated processes,
11118                // since they don't have a persistent identity.
11119                mProcessCrashTimes.put(r.info.processName, r.uid,
11120                        SystemClock.uptimeMillis());
11121            }
11122            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11123                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11124            }
11125        }
11126
11127        if (appErrorIntent != null) {
11128            try {
11129                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11130            } catch (ActivityNotFoundException e) {
11131                Slog.w(TAG, "bug report receiver dissappeared", e);
11132            }
11133        }
11134    }
11135
11136    Intent createAppErrorIntentLocked(ProcessRecord r,
11137            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11138        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11139        if (report == null) {
11140            return null;
11141        }
11142        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11143        result.setComponent(r.errorReportReceiver);
11144        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11145        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11146        return result;
11147    }
11148
11149    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11150            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11151        if (r.errorReportReceiver == null) {
11152            return null;
11153        }
11154
11155        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11156            return null;
11157        }
11158
11159        ApplicationErrorReport report = new ApplicationErrorReport();
11160        report.packageName = r.info.packageName;
11161        report.installerPackageName = r.errorReportReceiver.getPackageName();
11162        report.processName = r.processName;
11163        report.time = timeMillis;
11164        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11165
11166        if (r.crashing || r.forceCrashReport) {
11167            report.type = ApplicationErrorReport.TYPE_CRASH;
11168            report.crashInfo = crashInfo;
11169        } else if (r.notResponding) {
11170            report.type = ApplicationErrorReport.TYPE_ANR;
11171            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11172
11173            report.anrInfo.activity = r.notRespondingReport.tag;
11174            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11175            report.anrInfo.info = r.notRespondingReport.longMsg;
11176        }
11177
11178        return report;
11179    }
11180
11181    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11182        enforceNotIsolatedCaller("getProcessesInErrorState");
11183        // assume our apps are happy - lazy create the list
11184        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11185
11186        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11187                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11188        int userId = UserHandle.getUserId(Binder.getCallingUid());
11189
11190        synchronized (this) {
11191
11192            // iterate across all processes
11193            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11194                ProcessRecord app = mLruProcesses.get(i);
11195                if (!allUsers && app.userId != userId) {
11196                    continue;
11197                }
11198                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11199                    // This one's in trouble, so we'll generate a report for it
11200                    // crashes are higher priority (in case there's a crash *and* an anr)
11201                    ActivityManager.ProcessErrorStateInfo report = null;
11202                    if (app.crashing) {
11203                        report = app.crashingReport;
11204                    } else if (app.notResponding) {
11205                        report = app.notRespondingReport;
11206                    }
11207
11208                    if (report != null) {
11209                        if (errList == null) {
11210                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11211                        }
11212                        errList.add(report);
11213                    } else {
11214                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11215                                " crashing = " + app.crashing +
11216                                " notResponding = " + app.notResponding);
11217                    }
11218                }
11219            }
11220        }
11221
11222        return errList;
11223    }
11224
11225    static int procStateToImportance(int procState, int memAdj,
11226            ActivityManager.RunningAppProcessInfo currApp) {
11227        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11228        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11229            currApp.lru = memAdj;
11230        } else {
11231            currApp.lru = 0;
11232        }
11233        return imp;
11234    }
11235
11236    private void fillInProcMemInfo(ProcessRecord app,
11237            ActivityManager.RunningAppProcessInfo outInfo) {
11238        outInfo.pid = app.pid;
11239        outInfo.uid = app.info.uid;
11240        if (mHeavyWeightProcess == app) {
11241            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11242        }
11243        if (app.persistent) {
11244            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11245        }
11246        if (app.activities.size() > 0) {
11247            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11248        }
11249        outInfo.lastTrimLevel = app.trimMemoryLevel;
11250        int adj = app.curAdj;
11251        int procState = app.curProcState;
11252        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11253        outInfo.importanceReasonCode = app.adjTypeCode;
11254        outInfo.processState = app.curProcState;
11255    }
11256
11257    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11258        enforceNotIsolatedCaller("getRunningAppProcesses");
11259        // Lazy instantiation of list
11260        List<ActivityManager.RunningAppProcessInfo> runList = null;
11261        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11262                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11263        int userId = UserHandle.getUserId(Binder.getCallingUid());
11264        synchronized (this) {
11265            // Iterate across all processes
11266            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11267                ProcessRecord app = mLruProcesses.get(i);
11268                if (!allUsers && app.userId != userId) {
11269                    continue;
11270                }
11271                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11272                    // Generate process state info for running application
11273                    ActivityManager.RunningAppProcessInfo currApp =
11274                        new ActivityManager.RunningAppProcessInfo(app.processName,
11275                                app.pid, app.getPackageList());
11276                    fillInProcMemInfo(app, currApp);
11277                    if (app.adjSource instanceof ProcessRecord) {
11278                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11279                        currApp.importanceReasonImportance =
11280                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11281                                        app.adjSourceProcState);
11282                    } else if (app.adjSource instanceof ActivityRecord) {
11283                        ActivityRecord r = (ActivityRecord)app.adjSource;
11284                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11285                    }
11286                    if (app.adjTarget instanceof ComponentName) {
11287                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11288                    }
11289                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11290                    //        + " lru=" + currApp.lru);
11291                    if (runList == null) {
11292                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11293                    }
11294                    runList.add(currApp);
11295                }
11296            }
11297        }
11298        return runList;
11299    }
11300
11301    public List<ApplicationInfo> getRunningExternalApplications() {
11302        enforceNotIsolatedCaller("getRunningExternalApplications");
11303        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11304        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11305        if (runningApps != null && runningApps.size() > 0) {
11306            Set<String> extList = new HashSet<String>();
11307            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11308                if (app.pkgList != null) {
11309                    for (String pkg : app.pkgList) {
11310                        extList.add(pkg);
11311                    }
11312                }
11313            }
11314            IPackageManager pm = AppGlobals.getPackageManager();
11315            for (String pkg : extList) {
11316                try {
11317                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11318                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11319                        retList.add(info);
11320                    }
11321                } catch (RemoteException e) {
11322                }
11323            }
11324        }
11325        return retList;
11326    }
11327
11328    @Override
11329    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11330        enforceNotIsolatedCaller("getMyMemoryState");
11331        synchronized (this) {
11332            ProcessRecord proc;
11333            synchronized (mPidsSelfLocked) {
11334                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11335            }
11336            fillInProcMemInfo(proc, outInfo);
11337        }
11338    }
11339
11340    @Override
11341    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11342        if (checkCallingPermission(android.Manifest.permission.DUMP)
11343                != PackageManager.PERMISSION_GRANTED) {
11344            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11345                    + Binder.getCallingPid()
11346                    + ", uid=" + Binder.getCallingUid()
11347                    + " without permission "
11348                    + android.Manifest.permission.DUMP);
11349            return;
11350        }
11351
11352        boolean dumpAll = false;
11353        boolean dumpClient = false;
11354        String dumpPackage = null;
11355
11356        int opti = 0;
11357        while (opti < args.length) {
11358            String opt = args[opti];
11359            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11360                break;
11361            }
11362            opti++;
11363            if ("-a".equals(opt)) {
11364                dumpAll = true;
11365            } else if ("-c".equals(opt)) {
11366                dumpClient = true;
11367            } else if ("-h".equals(opt)) {
11368                pw.println("Activity manager dump options:");
11369                pw.println("  [-a] [-c] [-h] [cmd] ...");
11370                pw.println("  cmd may be one of:");
11371                pw.println("    a[ctivities]: activity stack state");
11372                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11373                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11374                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11375                pw.println("    o[om]: out of memory management");
11376                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11377                pw.println("    provider [COMP_SPEC]: provider client-side state");
11378                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11379                pw.println("    service [COMP_SPEC]: service client-side state");
11380                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11381                pw.println("    all: dump all activities");
11382                pw.println("    top: dump the top activity");
11383                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11384                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11385                pw.println("    a partial substring in a component name, a");
11386                pw.println("    hex object identifier.");
11387                pw.println("  -a: include all available server state.");
11388                pw.println("  -c: include client state.");
11389                return;
11390            } else {
11391                pw.println("Unknown argument: " + opt + "; use -h for help");
11392            }
11393        }
11394
11395        long origId = Binder.clearCallingIdentity();
11396        boolean more = false;
11397        // Is the caller requesting to dump a particular piece of data?
11398        if (opti < args.length) {
11399            String cmd = args[opti];
11400            opti++;
11401            if ("activities".equals(cmd) || "a".equals(cmd)) {
11402                synchronized (this) {
11403                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11404                }
11405            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11406                String[] newArgs;
11407                String name;
11408                if (opti >= args.length) {
11409                    name = null;
11410                    newArgs = EMPTY_STRING_ARRAY;
11411                } else {
11412                    name = args[opti];
11413                    opti++;
11414                    newArgs = new String[args.length - opti];
11415                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11416                            args.length - opti);
11417                }
11418                synchronized (this) {
11419                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11420                }
11421            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11422                String[] newArgs;
11423                String name;
11424                if (opti >= args.length) {
11425                    name = null;
11426                    newArgs = EMPTY_STRING_ARRAY;
11427                } else {
11428                    name = args[opti];
11429                    opti++;
11430                    newArgs = new String[args.length - opti];
11431                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11432                            args.length - opti);
11433                }
11434                synchronized (this) {
11435                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11436                }
11437            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11438                String[] newArgs;
11439                String name;
11440                if (opti >= args.length) {
11441                    name = null;
11442                    newArgs = EMPTY_STRING_ARRAY;
11443                } else {
11444                    name = args[opti];
11445                    opti++;
11446                    newArgs = new String[args.length - opti];
11447                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11448                            args.length - opti);
11449                }
11450                synchronized (this) {
11451                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11452                }
11453            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11454                synchronized (this) {
11455                    dumpOomLocked(fd, pw, args, opti, true);
11456                }
11457            } else if ("provider".equals(cmd)) {
11458                String[] newArgs;
11459                String name;
11460                if (opti >= args.length) {
11461                    name = null;
11462                    newArgs = EMPTY_STRING_ARRAY;
11463                } else {
11464                    name = args[opti];
11465                    opti++;
11466                    newArgs = new String[args.length - opti];
11467                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11468                }
11469                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11470                    pw.println("No providers match: " + name);
11471                    pw.println("Use -h for help.");
11472                }
11473            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11474                synchronized (this) {
11475                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11476                }
11477            } else if ("service".equals(cmd)) {
11478                String[] newArgs;
11479                String name;
11480                if (opti >= args.length) {
11481                    name = null;
11482                    newArgs = EMPTY_STRING_ARRAY;
11483                } else {
11484                    name = args[opti];
11485                    opti++;
11486                    newArgs = new String[args.length - opti];
11487                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11488                            args.length - opti);
11489                }
11490                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11491                    pw.println("No services match: " + name);
11492                    pw.println("Use -h for help.");
11493                }
11494            } else if ("package".equals(cmd)) {
11495                String[] newArgs;
11496                if (opti >= args.length) {
11497                    pw.println("package: no package name specified");
11498                    pw.println("Use -h for help.");
11499                } else {
11500                    dumpPackage = args[opti];
11501                    opti++;
11502                    newArgs = new String[args.length - opti];
11503                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11504                            args.length - opti);
11505                    args = newArgs;
11506                    opti = 0;
11507                    more = true;
11508                }
11509            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11510                synchronized (this) {
11511                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11512                }
11513            } else {
11514                // Dumping a single activity?
11515                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11516                    pw.println("Bad activity command, or no activities match: " + cmd);
11517                    pw.println("Use -h for help.");
11518                }
11519            }
11520            if (!more) {
11521                Binder.restoreCallingIdentity(origId);
11522                return;
11523            }
11524        }
11525
11526        // No piece of data specified, dump everything.
11527        synchronized (this) {
11528            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11529            pw.println();
11530            if (dumpAll) {
11531                pw.println("-------------------------------------------------------------------------------");
11532            }
11533            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11534            pw.println();
11535            if (dumpAll) {
11536                pw.println("-------------------------------------------------------------------------------");
11537            }
11538            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11539            pw.println();
11540            if (dumpAll) {
11541                pw.println("-------------------------------------------------------------------------------");
11542            }
11543            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11544            pw.println();
11545            if (dumpAll) {
11546                pw.println("-------------------------------------------------------------------------------");
11547            }
11548            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11549            pw.println();
11550            if (dumpAll) {
11551                pw.println("-------------------------------------------------------------------------------");
11552            }
11553            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11554        }
11555        Binder.restoreCallingIdentity(origId);
11556    }
11557
11558    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11559            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11560        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11561
11562        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11563                dumpPackage);
11564        boolean needSep = printedAnything;
11565
11566        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11567                dumpPackage, needSep, "  mFocusedActivity: ");
11568        if (printed) {
11569            printedAnything = true;
11570            needSep = false;
11571        }
11572
11573        if (dumpPackage == null) {
11574            if (needSep) {
11575                pw.println();
11576            }
11577            needSep = true;
11578            printedAnything = true;
11579            mStackSupervisor.dump(pw, "  ");
11580        }
11581
11582        if (mRecentTasks.size() > 0) {
11583            boolean printedHeader = false;
11584
11585            final int N = mRecentTasks.size();
11586            for (int i=0; i<N; i++) {
11587                TaskRecord tr = mRecentTasks.get(i);
11588                if (dumpPackage != null) {
11589                    if (tr.realActivity == null ||
11590                            !dumpPackage.equals(tr.realActivity)) {
11591                        continue;
11592                    }
11593                }
11594                if (!printedHeader) {
11595                    if (needSep) {
11596                        pw.println();
11597                    }
11598                    pw.println("  Recent tasks:");
11599                    printedHeader = true;
11600                    printedAnything = true;
11601                }
11602                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11603                        pw.println(tr);
11604                if (dumpAll) {
11605                    mRecentTasks.get(i).dump(pw, "    ");
11606                }
11607            }
11608        }
11609
11610        if (!printedAnything) {
11611            pw.println("  (nothing)");
11612        }
11613    }
11614
11615    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11616            int opti, boolean dumpAll, String dumpPackage) {
11617        boolean needSep = false;
11618        boolean printedAnything = false;
11619        int numPers = 0;
11620
11621        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11622
11623        if (dumpAll) {
11624            final int NP = mProcessNames.getMap().size();
11625            for (int ip=0; ip<NP; ip++) {
11626                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11627                final int NA = procs.size();
11628                for (int ia=0; ia<NA; ia++) {
11629                    ProcessRecord r = procs.valueAt(ia);
11630                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11631                        continue;
11632                    }
11633                    if (!needSep) {
11634                        pw.println("  All known processes:");
11635                        needSep = true;
11636                        printedAnything = true;
11637                    }
11638                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11639                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11640                        pw.print(" "); pw.println(r);
11641                    r.dump(pw, "    ");
11642                    if (r.persistent) {
11643                        numPers++;
11644                    }
11645                }
11646            }
11647        }
11648
11649        if (mIsolatedProcesses.size() > 0) {
11650            boolean printed = false;
11651            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11652                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11653                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11654                    continue;
11655                }
11656                if (!printed) {
11657                    if (needSep) {
11658                        pw.println();
11659                    }
11660                    pw.println("  Isolated process list (sorted by uid):");
11661                    printedAnything = true;
11662                    printed = true;
11663                    needSep = true;
11664                }
11665                pw.println(String.format("%sIsolated #%2d: %s",
11666                        "    ", i, r.toString()));
11667            }
11668        }
11669
11670        if (mLruProcesses.size() > 0) {
11671            if (needSep) {
11672                pw.println();
11673            }
11674            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11675                    pw.print(" total, non-act at ");
11676                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11677                    pw.print(", non-svc at ");
11678                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11679                    pw.println("):");
11680            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11681            needSep = true;
11682            printedAnything = true;
11683        }
11684
11685        if (dumpAll || dumpPackage != null) {
11686            synchronized (mPidsSelfLocked) {
11687                boolean printed = false;
11688                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11689                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11690                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11691                        continue;
11692                    }
11693                    if (!printed) {
11694                        if (needSep) pw.println();
11695                        needSep = true;
11696                        pw.println("  PID mappings:");
11697                        printed = true;
11698                        printedAnything = true;
11699                    }
11700                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11701                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11702                }
11703            }
11704        }
11705
11706        if (mForegroundProcesses.size() > 0) {
11707            synchronized (mPidsSelfLocked) {
11708                boolean printed = false;
11709                for (int i=0; i<mForegroundProcesses.size(); i++) {
11710                    ProcessRecord r = mPidsSelfLocked.get(
11711                            mForegroundProcesses.valueAt(i).pid);
11712                    if (dumpPackage != null && (r == null
11713                            || !r.pkgList.containsKey(dumpPackage))) {
11714                        continue;
11715                    }
11716                    if (!printed) {
11717                        if (needSep) pw.println();
11718                        needSep = true;
11719                        pw.println("  Foreground Processes:");
11720                        printed = true;
11721                        printedAnything = true;
11722                    }
11723                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11724                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11725                }
11726            }
11727        }
11728
11729        if (mPersistentStartingProcesses.size() > 0) {
11730            if (needSep) pw.println();
11731            needSep = true;
11732            printedAnything = true;
11733            pw.println("  Persisent processes that are starting:");
11734            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11735                    "Starting Norm", "Restarting PERS", dumpPackage);
11736        }
11737
11738        if (mRemovedProcesses.size() > 0) {
11739            if (needSep) pw.println();
11740            needSep = true;
11741            printedAnything = true;
11742            pw.println("  Processes that are being removed:");
11743            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11744                    "Removed Norm", "Removed PERS", dumpPackage);
11745        }
11746
11747        if (mProcessesOnHold.size() > 0) {
11748            if (needSep) pw.println();
11749            needSep = true;
11750            printedAnything = true;
11751            pw.println("  Processes that are on old until the system is ready:");
11752            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11753                    "OnHold Norm", "OnHold PERS", dumpPackage);
11754        }
11755
11756        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11757
11758        if (mProcessCrashTimes.getMap().size() > 0) {
11759            boolean printed = false;
11760            long now = SystemClock.uptimeMillis();
11761            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11762            final int NP = pmap.size();
11763            for (int ip=0; ip<NP; ip++) {
11764                String pname = pmap.keyAt(ip);
11765                SparseArray<Long> uids = pmap.valueAt(ip);
11766                final int N = uids.size();
11767                for (int i=0; i<N; i++) {
11768                    int puid = uids.keyAt(i);
11769                    ProcessRecord r = mProcessNames.get(pname, puid);
11770                    if (dumpPackage != null && (r == null
11771                            || !r.pkgList.containsKey(dumpPackage))) {
11772                        continue;
11773                    }
11774                    if (!printed) {
11775                        if (needSep) pw.println();
11776                        needSep = true;
11777                        pw.println("  Time since processes crashed:");
11778                        printed = true;
11779                        printedAnything = true;
11780                    }
11781                    pw.print("    Process "); pw.print(pname);
11782                            pw.print(" uid "); pw.print(puid);
11783                            pw.print(": last crashed ");
11784                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11785                            pw.println(" ago");
11786                }
11787            }
11788        }
11789
11790        if (mBadProcesses.getMap().size() > 0) {
11791            boolean printed = false;
11792            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11793            final int NP = pmap.size();
11794            for (int ip=0; ip<NP; ip++) {
11795                String pname = pmap.keyAt(ip);
11796                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11797                final int N = uids.size();
11798                for (int i=0; i<N; i++) {
11799                    int puid = uids.keyAt(i);
11800                    ProcessRecord r = mProcessNames.get(pname, puid);
11801                    if (dumpPackage != null && (r == null
11802                            || !r.pkgList.containsKey(dumpPackage))) {
11803                        continue;
11804                    }
11805                    if (!printed) {
11806                        if (needSep) pw.println();
11807                        needSep = true;
11808                        pw.println("  Bad processes:");
11809                        printedAnything = true;
11810                    }
11811                    BadProcessInfo info = uids.valueAt(i);
11812                    pw.print("    Bad process "); pw.print(pname);
11813                            pw.print(" uid "); pw.print(puid);
11814                            pw.print(": crashed at time "); pw.println(info.time);
11815                    if (info.shortMsg != null) {
11816                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11817                    }
11818                    if (info.longMsg != null) {
11819                        pw.print("      Long msg: "); pw.println(info.longMsg);
11820                    }
11821                    if (info.stack != null) {
11822                        pw.println("      Stack:");
11823                        int lastPos = 0;
11824                        for (int pos=0; pos<info.stack.length(); pos++) {
11825                            if (info.stack.charAt(pos) == '\n') {
11826                                pw.print("        ");
11827                                pw.write(info.stack, lastPos, pos-lastPos);
11828                                pw.println();
11829                                lastPos = pos+1;
11830                            }
11831                        }
11832                        if (lastPos < info.stack.length()) {
11833                            pw.print("        ");
11834                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11835                            pw.println();
11836                        }
11837                    }
11838                }
11839            }
11840        }
11841
11842        if (dumpPackage == null) {
11843            pw.println();
11844            needSep = false;
11845            pw.println("  mStartedUsers:");
11846            for (int i=0; i<mStartedUsers.size(); i++) {
11847                UserStartedState uss = mStartedUsers.valueAt(i);
11848                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11849                        pw.print(": "); uss.dump("", pw);
11850            }
11851            pw.print("  mStartedUserArray: [");
11852            for (int i=0; i<mStartedUserArray.length; i++) {
11853                if (i > 0) pw.print(", ");
11854                pw.print(mStartedUserArray[i]);
11855            }
11856            pw.println("]");
11857            pw.print("  mUserLru: [");
11858            for (int i=0; i<mUserLru.size(); i++) {
11859                if (i > 0) pw.print(", ");
11860                pw.print(mUserLru.get(i));
11861            }
11862            pw.println("]");
11863            if (dumpAll) {
11864                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11865            }
11866            synchronized (mUserProfileGroupIdsSelfLocked) {
11867                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11868                    pw.println("  mUserProfileGroupIds:");
11869                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11870                        pw.print("    User #");
11871                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11872                        pw.print(" -> profile #");
11873                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11874                    }
11875                }
11876            }
11877        }
11878        if (mHomeProcess != null && (dumpPackage == null
11879                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11880            if (needSep) {
11881                pw.println();
11882                needSep = false;
11883            }
11884            pw.println("  mHomeProcess: " + mHomeProcess);
11885        }
11886        if (mPreviousProcess != null && (dumpPackage == null
11887                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11888            if (needSep) {
11889                pw.println();
11890                needSep = false;
11891            }
11892            pw.println("  mPreviousProcess: " + mPreviousProcess);
11893        }
11894        if (dumpAll) {
11895            StringBuilder sb = new StringBuilder(128);
11896            sb.append("  mPreviousProcessVisibleTime: ");
11897            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11898            pw.println(sb);
11899        }
11900        if (mHeavyWeightProcess != null && (dumpPackage == null
11901                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11902            if (needSep) {
11903                pw.println();
11904                needSep = false;
11905            }
11906            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11907        }
11908        if (dumpPackage == null) {
11909            pw.println("  mConfiguration: " + mConfiguration);
11910        }
11911        if (dumpAll) {
11912            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11913            if (mCompatModePackages.getPackages().size() > 0) {
11914                boolean printed = false;
11915                for (Map.Entry<String, Integer> entry
11916                        : mCompatModePackages.getPackages().entrySet()) {
11917                    String pkg = entry.getKey();
11918                    int mode = entry.getValue();
11919                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11920                        continue;
11921                    }
11922                    if (!printed) {
11923                        pw.println("  mScreenCompatPackages:");
11924                        printed = true;
11925                    }
11926                    pw.print("    "); pw.print(pkg); pw.print(": ");
11927                            pw.print(mode); pw.println();
11928                }
11929            }
11930        }
11931        if (dumpPackage == null) {
11932            if (mSleeping || mWentToSleep || mLockScreenShown) {
11933                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11934                        + " mLockScreenShown " + mLockScreenShown);
11935            }
11936            if (mShuttingDown || mRunningVoice) {
11937                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11938            }
11939        }
11940        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11941                || mOrigWaitForDebugger) {
11942            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11943                    || dumpPackage.equals(mOrigDebugApp)) {
11944                if (needSep) {
11945                    pw.println();
11946                    needSep = false;
11947                }
11948                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11949                        + " mDebugTransient=" + mDebugTransient
11950                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11951            }
11952        }
11953        if (mOpenGlTraceApp != null) {
11954            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11955                if (needSep) {
11956                    pw.println();
11957                    needSep = false;
11958                }
11959                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11960            }
11961        }
11962        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11963                || mProfileFd != null) {
11964            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11965                if (needSep) {
11966                    pw.println();
11967                    needSep = false;
11968                }
11969                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11970                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11971                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11972                        + mAutoStopProfiler);
11973            }
11974        }
11975        if (dumpPackage == null) {
11976            if (mAlwaysFinishActivities || mController != null) {
11977                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11978                        + " mController=" + mController);
11979            }
11980            if (dumpAll) {
11981                pw.println("  Total persistent processes: " + numPers);
11982                pw.println("  mProcessesReady=" + mProcessesReady
11983                        + " mSystemReady=" + mSystemReady);
11984                pw.println("  mBooting=" + mBooting
11985                        + " mBooted=" + mBooted
11986                        + " mFactoryTest=" + mFactoryTest);
11987                pw.print("  mLastPowerCheckRealtime=");
11988                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11989                        pw.println("");
11990                pw.print("  mLastPowerCheckUptime=");
11991                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11992                        pw.println("");
11993                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11994                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11995                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11996                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11997                        + " (" + mLruProcesses.size() + " total)"
11998                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11999                        + " mNumServiceProcs=" + mNumServiceProcs
12000                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12001                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12002                        + " mLastMemoryLevel" + mLastMemoryLevel
12003                        + " mLastNumProcesses" + mLastNumProcesses);
12004                long now = SystemClock.uptimeMillis();
12005                pw.print("  mLastIdleTime=");
12006                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12007                        pw.print(" mLowRamSinceLastIdle=");
12008                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12009                        pw.println();
12010            }
12011        }
12012
12013        if (!printedAnything) {
12014            pw.println("  (nothing)");
12015        }
12016    }
12017
12018    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12019            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12020        if (mProcessesToGc.size() > 0) {
12021            boolean printed = false;
12022            long now = SystemClock.uptimeMillis();
12023            for (int i=0; i<mProcessesToGc.size(); i++) {
12024                ProcessRecord proc = mProcessesToGc.get(i);
12025                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12026                    continue;
12027                }
12028                if (!printed) {
12029                    if (needSep) pw.println();
12030                    needSep = true;
12031                    pw.println("  Processes that are waiting to GC:");
12032                    printed = true;
12033                }
12034                pw.print("    Process "); pw.println(proc);
12035                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12036                        pw.print(", last gced=");
12037                        pw.print(now-proc.lastRequestedGc);
12038                        pw.print(" ms ago, last lowMem=");
12039                        pw.print(now-proc.lastLowMemory);
12040                        pw.println(" ms ago");
12041
12042            }
12043        }
12044        return needSep;
12045    }
12046
12047    void printOomLevel(PrintWriter pw, String name, int adj) {
12048        pw.print("    ");
12049        if (adj >= 0) {
12050            pw.print(' ');
12051            if (adj < 10) pw.print(' ');
12052        } else {
12053            if (adj > -10) pw.print(' ');
12054        }
12055        pw.print(adj);
12056        pw.print(": ");
12057        pw.print(name);
12058        pw.print(" (");
12059        pw.print(mProcessList.getMemLevel(adj)/1024);
12060        pw.println(" kB)");
12061    }
12062
12063    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12064            int opti, boolean dumpAll) {
12065        boolean needSep = false;
12066
12067        if (mLruProcesses.size() > 0) {
12068            if (needSep) pw.println();
12069            needSep = true;
12070            pw.println("  OOM levels:");
12071            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12072            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12073            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12074            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12075            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12076            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12077            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12078            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12079            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12080            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12081            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12082            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12083            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12084
12085            if (needSep) pw.println();
12086            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12087                    pw.print(" total, non-act at ");
12088                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12089                    pw.print(", non-svc at ");
12090                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12091                    pw.println("):");
12092            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12093            needSep = true;
12094        }
12095
12096        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12097
12098        pw.println();
12099        pw.println("  mHomeProcess: " + mHomeProcess);
12100        pw.println("  mPreviousProcess: " + mPreviousProcess);
12101        if (mHeavyWeightProcess != null) {
12102            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12103        }
12104
12105        return true;
12106    }
12107
12108    /**
12109     * There are three ways to call this:
12110     *  - no provider specified: dump all the providers
12111     *  - a flattened component name that matched an existing provider was specified as the
12112     *    first arg: dump that one provider
12113     *  - the first arg isn't the flattened component name of an existing provider:
12114     *    dump all providers whose component contains the first arg as a substring
12115     */
12116    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12117            int opti, boolean dumpAll) {
12118        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12119    }
12120
12121    static class ItemMatcher {
12122        ArrayList<ComponentName> components;
12123        ArrayList<String> strings;
12124        ArrayList<Integer> objects;
12125        boolean all;
12126
12127        ItemMatcher() {
12128            all = true;
12129        }
12130
12131        void build(String name) {
12132            ComponentName componentName = ComponentName.unflattenFromString(name);
12133            if (componentName != null) {
12134                if (components == null) {
12135                    components = new ArrayList<ComponentName>();
12136                }
12137                components.add(componentName);
12138                all = false;
12139            } else {
12140                int objectId = 0;
12141                // Not a '/' separated full component name; maybe an object ID?
12142                try {
12143                    objectId = Integer.parseInt(name, 16);
12144                    if (objects == null) {
12145                        objects = new ArrayList<Integer>();
12146                    }
12147                    objects.add(objectId);
12148                    all = false;
12149                } catch (RuntimeException e) {
12150                    // Not an integer; just do string match.
12151                    if (strings == null) {
12152                        strings = new ArrayList<String>();
12153                    }
12154                    strings.add(name);
12155                    all = false;
12156                }
12157            }
12158        }
12159
12160        int build(String[] args, int opti) {
12161            for (; opti<args.length; opti++) {
12162                String name = args[opti];
12163                if ("--".equals(name)) {
12164                    return opti+1;
12165                }
12166                build(name);
12167            }
12168            return opti;
12169        }
12170
12171        boolean match(Object object, ComponentName comp) {
12172            if (all) {
12173                return true;
12174            }
12175            if (components != null) {
12176                for (int i=0; i<components.size(); i++) {
12177                    if (components.get(i).equals(comp)) {
12178                        return true;
12179                    }
12180                }
12181            }
12182            if (objects != null) {
12183                for (int i=0; i<objects.size(); i++) {
12184                    if (System.identityHashCode(object) == objects.get(i)) {
12185                        return true;
12186                    }
12187                }
12188            }
12189            if (strings != null) {
12190                String flat = comp.flattenToString();
12191                for (int i=0; i<strings.size(); i++) {
12192                    if (flat.contains(strings.get(i))) {
12193                        return true;
12194                    }
12195                }
12196            }
12197            return false;
12198        }
12199    }
12200
12201    /**
12202     * There are three things that cmd can be:
12203     *  - a flattened component name that matches an existing activity
12204     *  - the cmd arg isn't the flattened component name of an existing activity:
12205     *    dump all activity whose component contains the cmd as a substring
12206     *  - A hex number of the ActivityRecord object instance.
12207     */
12208    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12209            int opti, boolean dumpAll) {
12210        ArrayList<ActivityRecord> activities;
12211
12212        synchronized (this) {
12213            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12214        }
12215
12216        if (activities.size() <= 0) {
12217            return false;
12218        }
12219
12220        String[] newArgs = new String[args.length - opti];
12221        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12222
12223        TaskRecord lastTask = null;
12224        boolean needSep = false;
12225        for (int i=activities.size()-1; i>=0; i--) {
12226            ActivityRecord r = activities.get(i);
12227            if (needSep) {
12228                pw.println();
12229            }
12230            needSep = true;
12231            synchronized (this) {
12232                if (lastTask != r.task) {
12233                    lastTask = r.task;
12234                    pw.print("TASK "); pw.print(lastTask.affinity);
12235                            pw.print(" id="); pw.println(lastTask.taskId);
12236                    if (dumpAll) {
12237                        lastTask.dump(pw, "  ");
12238                    }
12239                }
12240            }
12241            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12242        }
12243        return true;
12244    }
12245
12246    /**
12247     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12248     * there is a thread associated with the activity.
12249     */
12250    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12251            final ActivityRecord r, String[] args, boolean dumpAll) {
12252        String innerPrefix = prefix + "  ";
12253        synchronized (this) {
12254            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12255                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12256                    pw.print(" pid=");
12257                    if (r.app != null) pw.println(r.app.pid);
12258                    else pw.println("(not running)");
12259            if (dumpAll) {
12260                r.dump(pw, innerPrefix);
12261            }
12262        }
12263        if (r.app != null && r.app.thread != null) {
12264            // flush anything that is already in the PrintWriter since the thread is going
12265            // to write to the file descriptor directly
12266            pw.flush();
12267            try {
12268                TransferPipe tp = new TransferPipe();
12269                try {
12270                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12271                            r.appToken, innerPrefix, args);
12272                    tp.go(fd);
12273                } finally {
12274                    tp.kill();
12275                }
12276            } catch (IOException e) {
12277                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12278            } catch (RemoteException e) {
12279                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12280            }
12281        }
12282    }
12283
12284    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12285            int opti, boolean dumpAll, String dumpPackage) {
12286        boolean needSep = false;
12287        boolean onlyHistory = false;
12288        boolean printedAnything = false;
12289
12290        if ("history".equals(dumpPackage)) {
12291            if (opti < args.length && "-s".equals(args[opti])) {
12292                dumpAll = false;
12293            }
12294            onlyHistory = true;
12295            dumpPackage = null;
12296        }
12297
12298        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12299        if (!onlyHistory && dumpAll) {
12300            if (mRegisteredReceivers.size() > 0) {
12301                boolean printed = false;
12302                Iterator it = mRegisteredReceivers.values().iterator();
12303                while (it.hasNext()) {
12304                    ReceiverList r = (ReceiverList)it.next();
12305                    if (dumpPackage != null && (r.app == null ||
12306                            !dumpPackage.equals(r.app.info.packageName))) {
12307                        continue;
12308                    }
12309                    if (!printed) {
12310                        pw.println("  Registered Receivers:");
12311                        needSep = true;
12312                        printed = true;
12313                        printedAnything = true;
12314                    }
12315                    pw.print("  * "); pw.println(r);
12316                    r.dump(pw, "    ");
12317                }
12318            }
12319
12320            if (mReceiverResolver.dump(pw, needSep ?
12321                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12322                    "    ", dumpPackage, false)) {
12323                needSep = true;
12324                printedAnything = true;
12325            }
12326        }
12327
12328        for (BroadcastQueue q : mBroadcastQueues) {
12329            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12330            printedAnything |= needSep;
12331        }
12332
12333        needSep = true;
12334
12335        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12336            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12337                if (needSep) {
12338                    pw.println();
12339                }
12340                needSep = true;
12341                printedAnything = true;
12342                pw.print("  Sticky broadcasts for user ");
12343                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12344                StringBuilder sb = new StringBuilder(128);
12345                for (Map.Entry<String, ArrayList<Intent>> ent
12346                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12347                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12348                    if (dumpAll) {
12349                        pw.println(":");
12350                        ArrayList<Intent> intents = ent.getValue();
12351                        final int N = intents.size();
12352                        for (int i=0; i<N; i++) {
12353                            sb.setLength(0);
12354                            sb.append("    Intent: ");
12355                            intents.get(i).toShortString(sb, false, true, false, false);
12356                            pw.println(sb.toString());
12357                            Bundle bundle = intents.get(i).getExtras();
12358                            if (bundle != null) {
12359                                pw.print("      ");
12360                                pw.println(bundle.toString());
12361                            }
12362                        }
12363                    } else {
12364                        pw.println("");
12365                    }
12366                }
12367            }
12368        }
12369
12370        if (!onlyHistory && dumpAll) {
12371            pw.println();
12372            for (BroadcastQueue queue : mBroadcastQueues) {
12373                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12374                        + queue.mBroadcastsScheduled);
12375            }
12376            pw.println("  mHandler:");
12377            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12378            needSep = true;
12379            printedAnything = true;
12380        }
12381
12382        if (!printedAnything) {
12383            pw.println("  (nothing)");
12384        }
12385    }
12386
12387    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12388            int opti, boolean dumpAll, String dumpPackage) {
12389        boolean needSep;
12390        boolean printedAnything = false;
12391
12392        ItemMatcher matcher = new ItemMatcher();
12393        matcher.build(args, opti);
12394
12395        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12396
12397        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12398        printedAnything |= needSep;
12399
12400        if (mLaunchingProviders.size() > 0) {
12401            boolean printed = false;
12402            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12403                ContentProviderRecord r = mLaunchingProviders.get(i);
12404                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12405                    continue;
12406                }
12407                if (!printed) {
12408                    if (needSep) pw.println();
12409                    needSep = true;
12410                    pw.println("  Launching content providers:");
12411                    printed = true;
12412                    printedAnything = true;
12413                }
12414                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12415                        pw.println(r);
12416            }
12417        }
12418
12419        if (mGrantedUriPermissions.size() > 0) {
12420            boolean printed = false;
12421            int dumpUid = -2;
12422            if (dumpPackage != null) {
12423                try {
12424                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12425                } catch (NameNotFoundException e) {
12426                    dumpUid = -1;
12427                }
12428            }
12429            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12430                int uid = mGrantedUriPermissions.keyAt(i);
12431                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12432                    continue;
12433                }
12434                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12435                if (!printed) {
12436                    if (needSep) pw.println();
12437                    needSep = true;
12438                    pw.println("  Granted Uri Permissions:");
12439                    printed = true;
12440                    printedAnything = true;
12441                }
12442                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12443                for (UriPermission perm : perms.values()) {
12444                    pw.print("    "); pw.println(perm);
12445                    if (dumpAll) {
12446                        perm.dump(pw, "      ");
12447                    }
12448                }
12449            }
12450        }
12451
12452        if (!printedAnything) {
12453            pw.println("  (nothing)");
12454        }
12455    }
12456
12457    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12458            int opti, boolean dumpAll, String dumpPackage) {
12459        boolean printed = false;
12460
12461        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12462
12463        if (mIntentSenderRecords.size() > 0) {
12464            Iterator<WeakReference<PendingIntentRecord>> it
12465                    = mIntentSenderRecords.values().iterator();
12466            while (it.hasNext()) {
12467                WeakReference<PendingIntentRecord> ref = it.next();
12468                PendingIntentRecord rec = ref != null ? ref.get(): null;
12469                if (dumpPackage != null && (rec == null
12470                        || !dumpPackage.equals(rec.key.packageName))) {
12471                    continue;
12472                }
12473                printed = true;
12474                if (rec != null) {
12475                    pw.print("  * "); pw.println(rec);
12476                    if (dumpAll) {
12477                        rec.dump(pw, "    ");
12478                    }
12479                } else {
12480                    pw.print("  * "); pw.println(ref);
12481                }
12482            }
12483        }
12484
12485        if (!printed) {
12486            pw.println("  (nothing)");
12487        }
12488    }
12489
12490    private static final int dumpProcessList(PrintWriter pw,
12491            ActivityManagerService service, List list,
12492            String prefix, String normalLabel, String persistentLabel,
12493            String dumpPackage) {
12494        int numPers = 0;
12495        final int N = list.size()-1;
12496        for (int i=N; i>=0; i--) {
12497            ProcessRecord r = (ProcessRecord)list.get(i);
12498            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12499                continue;
12500            }
12501            pw.println(String.format("%s%s #%2d: %s",
12502                    prefix, (r.persistent ? persistentLabel : normalLabel),
12503                    i, r.toString()));
12504            if (r.persistent) {
12505                numPers++;
12506            }
12507        }
12508        return numPers;
12509    }
12510
12511    private static final boolean dumpProcessOomList(PrintWriter pw,
12512            ActivityManagerService service, List<ProcessRecord> origList,
12513            String prefix, String normalLabel, String persistentLabel,
12514            boolean inclDetails, String dumpPackage) {
12515
12516        ArrayList<Pair<ProcessRecord, Integer>> list
12517                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12518        for (int i=0; i<origList.size(); i++) {
12519            ProcessRecord r = origList.get(i);
12520            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12521                continue;
12522            }
12523            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12524        }
12525
12526        if (list.size() <= 0) {
12527            return false;
12528        }
12529
12530        Comparator<Pair<ProcessRecord, Integer>> comparator
12531                = new Comparator<Pair<ProcessRecord, Integer>>() {
12532            @Override
12533            public int compare(Pair<ProcessRecord, Integer> object1,
12534                    Pair<ProcessRecord, Integer> object2) {
12535                if (object1.first.setAdj != object2.first.setAdj) {
12536                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12537                }
12538                if (object1.second.intValue() != object2.second.intValue()) {
12539                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12540                }
12541                return 0;
12542            }
12543        };
12544
12545        Collections.sort(list, comparator);
12546
12547        final long curRealtime = SystemClock.elapsedRealtime();
12548        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12549        final long curUptime = SystemClock.uptimeMillis();
12550        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12551
12552        for (int i=list.size()-1; i>=0; i--) {
12553            ProcessRecord r = list.get(i).first;
12554            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12555            char schedGroup;
12556            switch (r.setSchedGroup) {
12557                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12558                    schedGroup = 'B';
12559                    break;
12560                case Process.THREAD_GROUP_DEFAULT:
12561                    schedGroup = 'F';
12562                    break;
12563                default:
12564                    schedGroup = '?';
12565                    break;
12566            }
12567            char foreground;
12568            if (r.foregroundActivities) {
12569                foreground = 'A';
12570            } else if (r.foregroundServices) {
12571                foreground = 'S';
12572            } else {
12573                foreground = ' ';
12574            }
12575            String procState = ProcessList.makeProcStateString(r.curProcState);
12576            pw.print(prefix);
12577            pw.print(r.persistent ? persistentLabel : normalLabel);
12578            pw.print(" #");
12579            int num = (origList.size()-1)-list.get(i).second;
12580            if (num < 10) pw.print(' ');
12581            pw.print(num);
12582            pw.print(": ");
12583            pw.print(oomAdj);
12584            pw.print(' ');
12585            pw.print(schedGroup);
12586            pw.print('/');
12587            pw.print(foreground);
12588            pw.print('/');
12589            pw.print(procState);
12590            pw.print(" trm:");
12591            if (r.trimMemoryLevel < 10) pw.print(' ');
12592            pw.print(r.trimMemoryLevel);
12593            pw.print(' ');
12594            pw.print(r.toShortString());
12595            pw.print(" (");
12596            pw.print(r.adjType);
12597            pw.println(')');
12598            if (r.adjSource != null || r.adjTarget != null) {
12599                pw.print(prefix);
12600                pw.print("    ");
12601                if (r.adjTarget instanceof ComponentName) {
12602                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12603                } else if (r.adjTarget != null) {
12604                    pw.print(r.adjTarget.toString());
12605                } else {
12606                    pw.print("{null}");
12607                }
12608                pw.print("<=");
12609                if (r.adjSource instanceof ProcessRecord) {
12610                    pw.print("Proc{");
12611                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12612                    pw.println("}");
12613                } else if (r.adjSource != null) {
12614                    pw.println(r.adjSource.toString());
12615                } else {
12616                    pw.println("{null}");
12617                }
12618            }
12619            if (inclDetails) {
12620                pw.print(prefix);
12621                pw.print("    ");
12622                pw.print("oom: max="); pw.print(r.maxAdj);
12623                pw.print(" curRaw="); pw.print(r.curRawAdj);
12624                pw.print(" setRaw="); pw.print(r.setRawAdj);
12625                pw.print(" cur="); pw.print(r.curAdj);
12626                pw.print(" set="); pw.println(r.setAdj);
12627                pw.print(prefix);
12628                pw.print("    ");
12629                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12630                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12631                pw.print(" lastPss="); pw.print(r.lastPss);
12632                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12633                pw.print(prefix);
12634                pw.print("    ");
12635                pw.print("cached="); pw.print(r.cached);
12636                pw.print(" empty="); pw.print(r.empty);
12637                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12638
12639                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12640                    if (r.lastWakeTime != 0) {
12641                        long wtime;
12642                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12643                        synchronized (stats) {
12644                            wtime = stats.getProcessWakeTime(r.info.uid,
12645                                    r.pid, curRealtime);
12646                        }
12647                        long timeUsed = wtime - r.lastWakeTime;
12648                        pw.print(prefix);
12649                        pw.print("    ");
12650                        pw.print("keep awake over ");
12651                        TimeUtils.formatDuration(realtimeSince, pw);
12652                        pw.print(" used ");
12653                        TimeUtils.formatDuration(timeUsed, pw);
12654                        pw.print(" (");
12655                        pw.print((timeUsed*100)/realtimeSince);
12656                        pw.println("%)");
12657                    }
12658                    if (r.lastCpuTime != 0) {
12659                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12660                        pw.print(prefix);
12661                        pw.print("    ");
12662                        pw.print("run cpu over ");
12663                        TimeUtils.formatDuration(uptimeSince, pw);
12664                        pw.print(" used ");
12665                        TimeUtils.formatDuration(timeUsed, pw);
12666                        pw.print(" (");
12667                        pw.print((timeUsed*100)/uptimeSince);
12668                        pw.println("%)");
12669                    }
12670                }
12671            }
12672        }
12673        return true;
12674    }
12675
12676    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12677        ArrayList<ProcessRecord> procs;
12678        synchronized (this) {
12679            if (args != null && args.length > start
12680                    && args[start].charAt(0) != '-') {
12681                procs = new ArrayList<ProcessRecord>();
12682                int pid = -1;
12683                try {
12684                    pid = Integer.parseInt(args[start]);
12685                } catch (NumberFormatException e) {
12686                }
12687                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12688                    ProcessRecord proc = mLruProcesses.get(i);
12689                    if (proc.pid == pid) {
12690                        procs.add(proc);
12691                    } else if (proc.processName.equals(args[start])) {
12692                        procs.add(proc);
12693                    }
12694                }
12695                if (procs.size() <= 0) {
12696                    return null;
12697                }
12698            } else {
12699                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12700            }
12701        }
12702        return procs;
12703    }
12704
12705    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12706            PrintWriter pw, String[] args) {
12707        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12708        if (procs == null) {
12709            pw.println("No process found for: " + args[0]);
12710            return;
12711        }
12712
12713        long uptime = SystemClock.uptimeMillis();
12714        long realtime = SystemClock.elapsedRealtime();
12715        pw.println("Applications Graphics Acceleration Info:");
12716        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12717
12718        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12719            ProcessRecord r = procs.get(i);
12720            if (r.thread != null) {
12721                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12722                pw.flush();
12723                try {
12724                    TransferPipe tp = new TransferPipe();
12725                    try {
12726                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12727                        tp.go(fd);
12728                    } finally {
12729                        tp.kill();
12730                    }
12731                } catch (IOException e) {
12732                    pw.println("Failure while dumping the app: " + r);
12733                    pw.flush();
12734                } catch (RemoteException e) {
12735                    pw.println("Got a RemoteException while dumping the app " + r);
12736                    pw.flush();
12737                }
12738            }
12739        }
12740    }
12741
12742    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12743        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12744        if (procs == null) {
12745            pw.println("No process found for: " + args[0]);
12746            return;
12747        }
12748
12749        pw.println("Applications Database Info:");
12750
12751        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12752            ProcessRecord r = procs.get(i);
12753            if (r.thread != null) {
12754                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12755                pw.flush();
12756                try {
12757                    TransferPipe tp = new TransferPipe();
12758                    try {
12759                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12760                        tp.go(fd);
12761                    } finally {
12762                        tp.kill();
12763                    }
12764                } catch (IOException e) {
12765                    pw.println("Failure while dumping the app: " + r);
12766                    pw.flush();
12767                } catch (RemoteException e) {
12768                    pw.println("Got a RemoteException while dumping the app " + r);
12769                    pw.flush();
12770                }
12771            }
12772        }
12773    }
12774
12775    final static class MemItem {
12776        final boolean isProc;
12777        final String label;
12778        final String shortLabel;
12779        final long pss;
12780        final int id;
12781        final boolean hasActivities;
12782        ArrayList<MemItem> subitems;
12783
12784        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12785                boolean _hasActivities) {
12786            isProc = true;
12787            label = _label;
12788            shortLabel = _shortLabel;
12789            pss = _pss;
12790            id = _id;
12791            hasActivities = _hasActivities;
12792        }
12793
12794        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12795            isProc = false;
12796            label = _label;
12797            shortLabel = _shortLabel;
12798            pss = _pss;
12799            id = _id;
12800            hasActivities = false;
12801        }
12802    }
12803
12804    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12805            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12806        if (sort && !isCompact) {
12807            Collections.sort(items, new Comparator<MemItem>() {
12808                @Override
12809                public int compare(MemItem lhs, MemItem rhs) {
12810                    if (lhs.pss < rhs.pss) {
12811                        return 1;
12812                    } else if (lhs.pss > rhs.pss) {
12813                        return -1;
12814                    }
12815                    return 0;
12816                }
12817            });
12818        }
12819
12820        for (int i=0; i<items.size(); i++) {
12821            MemItem mi = items.get(i);
12822            if (!isCompact) {
12823                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12824            } else if (mi.isProc) {
12825                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12826                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12827                pw.println(mi.hasActivities ? ",a" : ",e");
12828            } else {
12829                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12830                pw.println(mi.pss);
12831            }
12832            if (mi.subitems != null) {
12833                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12834                        true, isCompact);
12835            }
12836        }
12837    }
12838
12839    // These are in KB.
12840    static final long[] DUMP_MEM_BUCKETS = new long[] {
12841        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12842        120*1024, 160*1024, 200*1024,
12843        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12844        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12845    };
12846
12847    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12848            boolean stackLike) {
12849        int start = label.lastIndexOf('.');
12850        if (start >= 0) start++;
12851        else start = 0;
12852        int end = label.length();
12853        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12854            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12855                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12856                out.append(bucket);
12857                out.append(stackLike ? "MB." : "MB ");
12858                out.append(label, start, end);
12859                return;
12860            }
12861        }
12862        out.append(memKB/1024);
12863        out.append(stackLike ? "MB." : "MB ");
12864        out.append(label, start, end);
12865    }
12866
12867    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12868            ProcessList.NATIVE_ADJ,
12869            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12870            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12871            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12872            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12873            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12874    };
12875    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12876            "Native",
12877            "System", "Persistent", "Foreground",
12878            "Visible", "Perceptible",
12879            "Heavy Weight", "Backup",
12880            "A Services", "Home",
12881            "Previous", "B Services", "Cached"
12882    };
12883    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12884            "native",
12885            "sys", "pers", "fore",
12886            "vis", "percept",
12887            "heavy", "backup",
12888            "servicea", "home",
12889            "prev", "serviceb", "cached"
12890    };
12891
12892    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12893            long realtime, boolean isCheckinRequest, boolean isCompact) {
12894        if (isCheckinRequest || isCompact) {
12895            // short checkin version
12896            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12897        } else {
12898            pw.println("Applications Memory Usage (kB):");
12899            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12900        }
12901    }
12902
12903    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12904            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12905        boolean dumpDetails = false;
12906        boolean dumpFullDetails = false;
12907        boolean dumpDalvik = false;
12908        boolean oomOnly = false;
12909        boolean isCompact = false;
12910        boolean localOnly = false;
12911
12912        int opti = 0;
12913        while (opti < args.length) {
12914            String opt = args[opti];
12915            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12916                break;
12917            }
12918            opti++;
12919            if ("-a".equals(opt)) {
12920                dumpDetails = true;
12921                dumpFullDetails = true;
12922                dumpDalvik = true;
12923            } else if ("-d".equals(opt)) {
12924                dumpDalvik = true;
12925            } else if ("-c".equals(opt)) {
12926                isCompact = true;
12927            } else if ("--oom".equals(opt)) {
12928                oomOnly = true;
12929            } else if ("--local".equals(opt)) {
12930                localOnly = true;
12931            } else if ("-h".equals(opt)) {
12932                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12933                pw.println("  -a: include all available information for each process.");
12934                pw.println("  -d: include dalvik details when dumping process details.");
12935                pw.println("  -c: dump in a compact machine-parseable representation.");
12936                pw.println("  --oom: only show processes organized by oom adj.");
12937                pw.println("  --local: only collect details locally, don't call process.");
12938                pw.println("If [process] is specified it can be the name or ");
12939                pw.println("pid of a specific process to dump.");
12940                return;
12941            } else {
12942                pw.println("Unknown argument: " + opt + "; use -h for help");
12943            }
12944        }
12945
12946        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12947        long uptime = SystemClock.uptimeMillis();
12948        long realtime = SystemClock.elapsedRealtime();
12949        final long[] tmpLong = new long[1];
12950
12951        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12952        if (procs == null) {
12953            // No Java processes.  Maybe they want to print a native process.
12954            if (args != null && args.length > opti
12955                    && args[opti].charAt(0) != '-') {
12956                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12957                        = new ArrayList<ProcessCpuTracker.Stats>();
12958                updateCpuStatsNow();
12959                int findPid = -1;
12960                try {
12961                    findPid = Integer.parseInt(args[opti]);
12962                } catch (NumberFormatException e) {
12963                }
12964                synchronized (mProcessCpuThread) {
12965                    final int N = mProcessCpuTracker.countStats();
12966                    for (int i=0; i<N; i++) {
12967                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12968                        if (st.pid == findPid || (st.baseName != null
12969                                && st.baseName.equals(args[opti]))) {
12970                            nativeProcs.add(st);
12971                        }
12972                    }
12973                }
12974                if (nativeProcs.size() > 0) {
12975                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12976                            isCompact);
12977                    Debug.MemoryInfo mi = null;
12978                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12979                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12980                        final int pid = r.pid;
12981                        if (!isCheckinRequest && dumpDetails) {
12982                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12983                        }
12984                        if (mi == null) {
12985                            mi = new Debug.MemoryInfo();
12986                        }
12987                        if (dumpDetails || (!brief && !oomOnly)) {
12988                            Debug.getMemoryInfo(pid, mi);
12989                        } else {
12990                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12991                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12992                        }
12993                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12994                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12995                        if (isCheckinRequest) {
12996                            pw.println();
12997                        }
12998                    }
12999                    return;
13000                }
13001            }
13002            pw.println("No process found for: " + args[opti]);
13003            return;
13004        }
13005
13006        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13007            dumpDetails = true;
13008        }
13009
13010        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13011
13012        String[] innerArgs = new String[args.length-opti];
13013        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13014
13015        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13016        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13017        long nativePss=0, dalvikPss=0, otherPss=0;
13018        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13019
13020        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13021        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13022                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13023
13024        long totalPss = 0;
13025        long cachedPss = 0;
13026
13027        Debug.MemoryInfo mi = null;
13028        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13029            final ProcessRecord r = procs.get(i);
13030            final IApplicationThread thread;
13031            final int pid;
13032            final int oomAdj;
13033            final boolean hasActivities;
13034            synchronized (this) {
13035                thread = r.thread;
13036                pid = r.pid;
13037                oomAdj = r.getSetAdjWithServices();
13038                hasActivities = r.activities.size() > 0;
13039            }
13040            if (thread != null) {
13041                if (!isCheckinRequest && dumpDetails) {
13042                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13043                }
13044                if (mi == null) {
13045                    mi = new Debug.MemoryInfo();
13046                }
13047                if (dumpDetails || (!brief && !oomOnly)) {
13048                    Debug.getMemoryInfo(pid, mi);
13049                } else {
13050                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13051                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13052                }
13053                if (dumpDetails) {
13054                    if (localOnly) {
13055                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13056                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13057                        if (isCheckinRequest) {
13058                            pw.println();
13059                        }
13060                    } else {
13061                        try {
13062                            pw.flush();
13063                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13064                                    dumpDalvik, innerArgs);
13065                        } catch (RemoteException e) {
13066                            if (!isCheckinRequest) {
13067                                pw.println("Got RemoteException!");
13068                                pw.flush();
13069                            }
13070                        }
13071                    }
13072                }
13073
13074                final long myTotalPss = mi.getTotalPss();
13075                final long myTotalUss = mi.getTotalUss();
13076
13077                synchronized (this) {
13078                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13079                        // Record this for posterity if the process has been stable.
13080                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13081                    }
13082                }
13083
13084                if (!isCheckinRequest && mi != null) {
13085                    totalPss += myTotalPss;
13086                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13087                            (hasActivities ? " / activities)" : ")"),
13088                            r.processName, myTotalPss, pid, hasActivities);
13089                    procMems.add(pssItem);
13090                    procMemsMap.put(pid, pssItem);
13091
13092                    nativePss += mi.nativePss;
13093                    dalvikPss += mi.dalvikPss;
13094                    otherPss += mi.otherPss;
13095                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13096                        long mem = mi.getOtherPss(j);
13097                        miscPss[j] += mem;
13098                        otherPss -= mem;
13099                    }
13100
13101                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13102                        cachedPss += myTotalPss;
13103                    }
13104
13105                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13106                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13107                                || oomIndex == (oomPss.length-1)) {
13108                            oomPss[oomIndex] += myTotalPss;
13109                            if (oomProcs[oomIndex] == null) {
13110                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13111                            }
13112                            oomProcs[oomIndex].add(pssItem);
13113                            break;
13114                        }
13115                    }
13116                }
13117            }
13118        }
13119
13120        long nativeProcTotalPss = 0;
13121
13122        if (!isCheckinRequest && procs.size() > 1) {
13123            // If we are showing aggregations, also look for native processes to
13124            // include so that our aggregations are more accurate.
13125            updateCpuStatsNow();
13126            synchronized (mProcessCpuThread) {
13127                final int N = mProcessCpuTracker.countStats();
13128                for (int i=0; i<N; i++) {
13129                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13130                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13131                        if (mi == null) {
13132                            mi = new Debug.MemoryInfo();
13133                        }
13134                        if (!brief && !oomOnly) {
13135                            Debug.getMemoryInfo(st.pid, mi);
13136                        } else {
13137                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13138                            mi.nativePrivateDirty = (int)tmpLong[0];
13139                        }
13140
13141                        final long myTotalPss = mi.getTotalPss();
13142                        totalPss += myTotalPss;
13143                        nativeProcTotalPss += myTotalPss;
13144
13145                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13146                                st.name, myTotalPss, st.pid, false);
13147                        procMems.add(pssItem);
13148
13149                        nativePss += mi.nativePss;
13150                        dalvikPss += mi.dalvikPss;
13151                        otherPss += mi.otherPss;
13152                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13153                            long mem = mi.getOtherPss(j);
13154                            miscPss[j] += mem;
13155                            otherPss -= mem;
13156                        }
13157                        oomPss[0] += myTotalPss;
13158                        if (oomProcs[0] == null) {
13159                            oomProcs[0] = new ArrayList<MemItem>();
13160                        }
13161                        oomProcs[0].add(pssItem);
13162                    }
13163                }
13164            }
13165
13166            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13167
13168            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13169            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13170            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13171            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13172                String label = Debug.MemoryInfo.getOtherLabel(j);
13173                catMems.add(new MemItem(label, label, miscPss[j], j));
13174            }
13175
13176            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13177            for (int j=0; j<oomPss.length; j++) {
13178                if (oomPss[j] != 0) {
13179                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13180                            : DUMP_MEM_OOM_LABEL[j];
13181                    MemItem item = new MemItem(label, label, oomPss[j],
13182                            DUMP_MEM_OOM_ADJ[j]);
13183                    item.subitems = oomProcs[j];
13184                    oomMems.add(item);
13185                }
13186            }
13187
13188            if (!brief && !oomOnly && !isCompact) {
13189                pw.println();
13190                pw.println("Total PSS by process:");
13191                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13192                pw.println();
13193            }
13194            if (!isCompact) {
13195                pw.println("Total PSS by OOM adjustment:");
13196            }
13197            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13198            if (!brief && !oomOnly) {
13199                PrintWriter out = categoryPw != null ? categoryPw : pw;
13200                if (!isCompact) {
13201                    out.println();
13202                    out.println("Total PSS by category:");
13203                }
13204                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13205            }
13206            if (!isCompact) {
13207                pw.println();
13208            }
13209            MemInfoReader memInfo = new MemInfoReader();
13210            memInfo.readMemInfo();
13211            if (nativeProcTotalPss > 0) {
13212                synchronized (this) {
13213                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13214                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13215                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13216                            nativeProcTotalPss);
13217                }
13218            }
13219            if (!brief) {
13220                if (!isCompact) {
13221                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13222                    pw.print(" kB (status ");
13223                    switch (mLastMemoryLevel) {
13224                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13225                            pw.println("normal)");
13226                            break;
13227                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13228                            pw.println("moderate)");
13229                            break;
13230                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13231                            pw.println("low)");
13232                            break;
13233                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13234                            pw.println("critical)");
13235                            break;
13236                        default:
13237                            pw.print(mLastMemoryLevel);
13238                            pw.println(")");
13239                            break;
13240                    }
13241                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13242                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13243                            pw.print(cachedPss); pw.print(" cached pss + ");
13244                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13245                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13246                } else {
13247                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13248                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13249                            + memInfo.getFreeSizeKb()); pw.print(",");
13250                    pw.println(totalPss - cachedPss);
13251                }
13252            }
13253            if (!isCompact) {
13254                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13255                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13256                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13257                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13258                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13259                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13260                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13261                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13262                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13263                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13264                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13265            }
13266            if (!brief) {
13267                if (memInfo.getZramTotalSizeKb() != 0) {
13268                    if (!isCompact) {
13269                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13270                                pw.print(" kB physical used for ");
13271                                pw.print(memInfo.getSwapTotalSizeKb()
13272                                        - memInfo.getSwapFreeSizeKb());
13273                                pw.print(" kB in swap (");
13274                                pw.print(memInfo.getSwapTotalSizeKb());
13275                                pw.println(" kB total swap)");
13276                    } else {
13277                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13278                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13279                                pw.println(memInfo.getSwapFreeSizeKb());
13280                    }
13281                }
13282                final int[] SINGLE_LONG_FORMAT = new int[] {
13283                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13284                };
13285                long[] longOut = new long[1];
13286                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13287                        SINGLE_LONG_FORMAT, null, longOut, null);
13288                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13289                longOut[0] = 0;
13290                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13291                        SINGLE_LONG_FORMAT, null, longOut, null);
13292                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13293                longOut[0] = 0;
13294                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13295                        SINGLE_LONG_FORMAT, null, longOut, null);
13296                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13297                longOut[0] = 0;
13298                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13299                        SINGLE_LONG_FORMAT, null, longOut, null);
13300                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13301                if (!isCompact) {
13302                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13303                        pw.print("      KSM: "); pw.print(sharing);
13304                                pw.print(" kB saved from shared ");
13305                                pw.print(shared); pw.println(" kB");
13306                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13307                                pw.print(voltile); pw.println(" kB volatile");
13308                    }
13309                    pw.print("   Tuning: ");
13310                    pw.print(ActivityManager.staticGetMemoryClass());
13311                    pw.print(" (large ");
13312                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13313                    pw.print("), oom ");
13314                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13315                    pw.print(" kB");
13316                    pw.print(", restore limit ");
13317                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13318                    pw.print(" kB");
13319                    if (ActivityManager.isLowRamDeviceStatic()) {
13320                        pw.print(" (low-ram)");
13321                    }
13322                    if (ActivityManager.isHighEndGfx()) {
13323                        pw.print(" (high-end-gfx)");
13324                    }
13325                    pw.println();
13326                } else {
13327                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13328                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13329                    pw.println(voltile);
13330                    pw.print("tuning,");
13331                    pw.print(ActivityManager.staticGetMemoryClass());
13332                    pw.print(',');
13333                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13334                    pw.print(',');
13335                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13336                    if (ActivityManager.isLowRamDeviceStatic()) {
13337                        pw.print(",low-ram");
13338                    }
13339                    if (ActivityManager.isHighEndGfx()) {
13340                        pw.print(",high-end-gfx");
13341                    }
13342                    pw.println();
13343                }
13344            }
13345        }
13346    }
13347
13348    /**
13349     * Searches array of arguments for the specified string
13350     * @param args array of argument strings
13351     * @param value value to search for
13352     * @return true if the value is contained in the array
13353     */
13354    private static boolean scanArgs(String[] args, String value) {
13355        if (args != null) {
13356            for (String arg : args) {
13357                if (value.equals(arg)) {
13358                    return true;
13359                }
13360            }
13361        }
13362        return false;
13363    }
13364
13365    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13366            ContentProviderRecord cpr, boolean always) {
13367        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13368
13369        if (!inLaunching || always) {
13370            synchronized (cpr) {
13371                cpr.launchingApp = null;
13372                cpr.notifyAll();
13373            }
13374            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13375            String names[] = cpr.info.authority.split(";");
13376            for (int j = 0; j < names.length; j++) {
13377                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13378            }
13379        }
13380
13381        for (int i=0; i<cpr.connections.size(); i++) {
13382            ContentProviderConnection conn = cpr.connections.get(i);
13383            if (conn.waiting) {
13384                // If this connection is waiting for the provider, then we don't
13385                // need to mess with its process unless we are always removing
13386                // or for some reason the provider is not currently launching.
13387                if (inLaunching && !always) {
13388                    continue;
13389                }
13390            }
13391            ProcessRecord capp = conn.client;
13392            conn.dead = true;
13393            if (conn.stableCount > 0) {
13394                if (!capp.persistent && capp.thread != null
13395                        && capp.pid != 0
13396                        && capp.pid != MY_PID) {
13397                    killUnneededProcessLocked(capp, "depends on provider "
13398                            + cpr.name.flattenToShortString()
13399                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13400                }
13401            } else if (capp.thread != null && conn.provider.provider != null) {
13402                try {
13403                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13404                } catch (RemoteException e) {
13405                }
13406                // In the protocol here, we don't expect the client to correctly
13407                // clean up this connection, we'll just remove it.
13408                cpr.connections.remove(i);
13409                conn.client.conProviders.remove(conn);
13410            }
13411        }
13412
13413        if (inLaunching && always) {
13414            mLaunchingProviders.remove(cpr);
13415        }
13416        return inLaunching;
13417    }
13418
13419    /**
13420     * Main code for cleaning up a process when it has gone away.  This is
13421     * called both as a result of the process dying, or directly when stopping
13422     * a process when running in single process mode.
13423     */
13424    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13425            boolean restarting, boolean allowRestart, int index) {
13426        if (index >= 0) {
13427            removeLruProcessLocked(app);
13428            ProcessList.remove(app.pid);
13429        }
13430
13431        mProcessesToGc.remove(app);
13432        mPendingPssProcesses.remove(app);
13433
13434        // Dismiss any open dialogs.
13435        if (app.crashDialog != null && !app.forceCrashReport) {
13436            app.crashDialog.dismiss();
13437            app.crashDialog = null;
13438        }
13439        if (app.anrDialog != null) {
13440            app.anrDialog.dismiss();
13441            app.anrDialog = null;
13442        }
13443        if (app.waitDialog != null) {
13444            app.waitDialog.dismiss();
13445            app.waitDialog = null;
13446        }
13447
13448        app.crashing = false;
13449        app.notResponding = false;
13450
13451        app.resetPackageList(mProcessStats);
13452        app.unlinkDeathRecipient();
13453        app.makeInactive(mProcessStats);
13454        app.waitingToKill = null;
13455        app.forcingToForeground = null;
13456        updateProcessForegroundLocked(app, false, false);
13457        app.foregroundActivities = false;
13458        app.hasShownUi = false;
13459        app.treatLikeActivity = false;
13460        app.hasAboveClient = false;
13461        app.hasClientActivities = false;
13462
13463        mServices.killServicesLocked(app, allowRestart);
13464
13465        boolean restart = false;
13466
13467        // Remove published content providers.
13468        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13469            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13470            final boolean always = app.bad || !allowRestart;
13471            if (removeDyingProviderLocked(app, cpr, always) || always) {
13472                // We left the provider in the launching list, need to
13473                // restart it.
13474                restart = true;
13475            }
13476
13477            cpr.provider = null;
13478            cpr.proc = null;
13479        }
13480        app.pubProviders.clear();
13481
13482        // Take care of any launching providers waiting for this process.
13483        if (checkAppInLaunchingProvidersLocked(app, false)) {
13484            restart = true;
13485        }
13486
13487        // Unregister from connected content providers.
13488        if (!app.conProviders.isEmpty()) {
13489            for (int i=0; i<app.conProviders.size(); i++) {
13490                ContentProviderConnection conn = app.conProviders.get(i);
13491                conn.provider.connections.remove(conn);
13492            }
13493            app.conProviders.clear();
13494        }
13495
13496        // At this point there may be remaining entries in mLaunchingProviders
13497        // where we were the only one waiting, so they are no longer of use.
13498        // Look for these and clean up if found.
13499        // XXX Commented out for now.  Trying to figure out a way to reproduce
13500        // the actual situation to identify what is actually going on.
13501        if (false) {
13502            for (int i=0; i<mLaunchingProviders.size(); i++) {
13503                ContentProviderRecord cpr = (ContentProviderRecord)
13504                        mLaunchingProviders.get(i);
13505                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13506                    synchronized (cpr) {
13507                        cpr.launchingApp = null;
13508                        cpr.notifyAll();
13509                    }
13510                }
13511            }
13512        }
13513
13514        skipCurrentReceiverLocked(app);
13515
13516        // Unregister any receivers.
13517        for (int i=app.receivers.size()-1; i>=0; i--) {
13518            removeReceiverLocked(app.receivers.valueAt(i));
13519        }
13520        app.receivers.clear();
13521
13522        // If the app is undergoing backup, tell the backup manager about it
13523        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13524            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13525                    + mBackupTarget.appInfo + " died during backup");
13526            try {
13527                IBackupManager bm = IBackupManager.Stub.asInterface(
13528                        ServiceManager.getService(Context.BACKUP_SERVICE));
13529                bm.agentDisconnected(app.info.packageName);
13530            } catch (RemoteException e) {
13531                // can't happen; backup manager is local
13532            }
13533        }
13534
13535        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13536            ProcessChangeItem item = mPendingProcessChanges.get(i);
13537            if (item.pid == app.pid) {
13538                mPendingProcessChanges.remove(i);
13539                mAvailProcessChanges.add(item);
13540            }
13541        }
13542        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13543
13544        // If the caller is restarting this app, then leave it in its
13545        // current lists and let the caller take care of it.
13546        if (restarting) {
13547            return;
13548        }
13549
13550        if (!app.persistent || app.isolated) {
13551            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13552                    "Removing non-persistent process during cleanup: " + app);
13553            mProcessNames.remove(app.processName, app.uid);
13554            mIsolatedProcesses.remove(app.uid);
13555            if (mHeavyWeightProcess == app) {
13556                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13557                        mHeavyWeightProcess.userId, 0));
13558                mHeavyWeightProcess = null;
13559            }
13560        } else if (!app.removed) {
13561            // This app is persistent, so we need to keep its record around.
13562            // If it is not already on the pending app list, add it there
13563            // and start a new process for it.
13564            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13565                mPersistentStartingProcesses.add(app);
13566                restart = true;
13567            }
13568        }
13569        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13570                "Clean-up removing on hold: " + app);
13571        mProcessesOnHold.remove(app);
13572
13573        if (app == mHomeProcess) {
13574            mHomeProcess = null;
13575        }
13576        if (app == mPreviousProcess) {
13577            mPreviousProcess = null;
13578        }
13579
13580        if (restart && !app.isolated) {
13581            // We have components that still need to be running in the
13582            // process, so re-launch it.
13583            mProcessNames.put(app.processName, app.uid, app);
13584            startProcessLocked(app, "restart", app.processName);
13585        } else if (app.pid > 0 && app.pid != MY_PID) {
13586            // Goodbye!
13587            boolean removed;
13588            synchronized (mPidsSelfLocked) {
13589                mPidsSelfLocked.remove(app.pid);
13590                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13591            }
13592            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13593            if (app.isolated) {
13594                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13595            }
13596            app.setPid(0);
13597        }
13598    }
13599
13600    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13601        // Look through the content providers we are waiting to have launched,
13602        // and if any run in this process then either schedule a restart of
13603        // the process or kill the client waiting for it if this process has
13604        // gone bad.
13605        int NL = mLaunchingProviders.size();
13606        boolean restart = false;
13607        for (int i=0; i<NL; i++) {
13608            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13609            if (cpr.launchingApp == app) {
13610                if (!alwaysBad && !app.bad) {
13611                    restart = true;
13612                } else {
13613                    removeDyingProviderLocked(app, cpr, true);
13614                    // cpr should have been removed from mLaunchingProviders
13615                    NL = mLaunchingProviders.size();
13616                    i--;
13617                }
13618            }
13619        }
13620        return restart;
13621    }
13622
13623    // =========================================================
13624    // SERVICES
13625    // =========================================================
13626
13627    @Override
13628    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13629            int flags) {
13630        enforceNotIsolatedCaller("getServices");
13631        synchronized (this) {
13632            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13633        }
13634    }
13635
13636    @Override
13637    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13638        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13639        synchronized (this) {
13640            return mServices.getRunningServiceControlPanelLocked(name);
13641        }
13642    }
13643
13644    @Override
13645    public ComponentName startService(IApplicationThread caller, Intent service,
13646            String resolvedType, int userId) {
13647        enforceNotIsolatedCaller("startService");
13648        // Refuse possible leaked file descriptors
13649        if (service != null && service.hasFileDescriptors() == true) {
13650            throw new IllegalArgumentException("File descriptors passed in Intent");
13651        }
13652
13653        if (DEBUG_SERVICE)
13654            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13655        synchronized(this) {
13656            final int callingPid = Binder.getCallingPid();
13657            final int callingUid = Binder.getCallingUid();
13658            final long origId = Binder.clearCallingIdentity();
13659            ComponentName res = mServices.startServiceLocked(caller, service,
13660                    resolvedType, callingPid, callingUid, userId);
13661            Binder.restoreCallingIdentity(origId);
13662            return res;
13663        }
13664    }
13665
13666    ComponentName startServiceInPackage(int uid,
13667            Intent service, String resolvedType, int userId) {
13668        synchronized(this) {
13669            if (DEBUG_SERVICE)
13670                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13671            final long origId = Binder.clearCallingIdentity();
13672            ComponentName res = mServices.startServiceLocked(null, service,
13673                    resolvedType, -1, uid, userId);
13674            Binder.restoreCallingIdentity(origId);
13675            return res;
13676        }
13677    }
13678
13679    @Override
13680    public int stopService(IApplicationThread caller, Intent service,
13681            String resolvedType, int userId) {
13682        enforceNotIsolatedCaller("stopService");
13683        // Refuse possible leaked file descriptors
13684        if (service != null && service.hasFileDescriptors() == true) {
13685            throw new IllegalArgumentException("File descriptors passed in Intent");
13686        }
13687
13688        synchronized(this) {
13689            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13690        }
13691    }
13692
13693    @Override
13694    public IBinder peekService(Intent service, String resolvedType) {
13695        enforceNotIsolatedCaller("peekService");
13696        // Refuse possible leaked file descriptors
13697        if (service != null && service.hasFileDescriptors() == true) {
13698            throw new IllegalArgumentException("File descriptors passed in Intent");
13699        }
13700        synchronized(this) {
13701            return mServices.peekServiceLocked(service, resolvedType);
13702        }
13703    }
13704
13705    @Override
13706    public boolean stopServiceToken(ComponentName className, IBinder token,
13707            int startId) {
13708        synchronized(this) {
13709            return mServices.stopServiceTokenLocked(className, token, startId);
13710        }
13711    }
13712
13713    @Override
13714    public void setServiceForeground(ComponentName className, IBinder token,
13715            int id, Notification notification, boolean removeNotification) {
13716        synchronized(this) {
13717            mServices.setServiceForegroundLocked(className, token, id, notification,
13718                    removeNotification);
13719        }
13720    }
13721
13722    @Override
13723    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13724            boolean requireFull, String name, String callerPackage) {
13725        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13726                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13727    }
13728
13729    int unsafeConvertIncomingUser(int userId) {
13730        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13731                ? mCurrentUserId : userId;
13732    }
13733
13734    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13735            int allowMode, String name, String callerPackage) {
13736        final int callingUserId = UserHandle.getUserId(callingUid);
13737        if (callingUserId == userId) {
13738            return userId;
13739        }
13740
13741        // Note that we may be accessing mCurrentUserId outside of a lock...
13742        // shouldn't be a big deal, if this is being called outside
13743        // of a locked context there is intrinsically a race with
13744        // the value the caller will receive and someone else changing it.
13745        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13746        // we will switch to the calling user if access to the current user fails.
13747        int targetUserId = unsafeConvertIncomingUser(userId);
13748
13749        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13750            final boolean allow;
13751            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13752                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13753                // If the caller has this permission, they always pass go.  And collect $200.
13754                allow = true;
13755            } else if (allowMode == ALLOW_FULL_ONLY) {
13756                // We require full access, sucks to be you.
13757                allow = false;
13758            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13759                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13760                // If the caller does not have either permission, they are always doomed.
13761                allow = false;
13762            } else if (allowMode == ALLOW_NON_FULL) {
13763                // We are blanket allowing non-full access, you lucky caller!
13764                allow = true;
13765            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13766                // We may or may not allow this depending on whether the two users are
13767                // in the same profile.
13768                synchronized (mUserProfileGroupIdsSelfLocked) {
13769                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13770                            UserInfo.NO_PROFILE_GROUP_ID);
13771                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13772                            UserInfo.NO_PROFILE_GROUP_ID);
13773                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13774                            && callingProfile == targetProfile;
13775                }
13776            } else {
13777                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13778            }
13779            if (!allow) {
13780                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13781                    // In this case, they would like to just execute as their
13782                    // owner user instead of failing.
13783                    targetUserId = callingUserId;
13784                } else {
13785                    StringBuilder builder = new StringBuilder(128);
13786                    builder.append("Permission Denial: ");
13787                    builder.append(name);
13788                    if (callerPackage != null) {
13789                        builder.append(" from ");
13790                        builder.append(callerPackage);
13791                    }
13792                    builder.append(" asks to run as user ");
13793                    builder.append(userId);
13794                    builder.append(" but is calling from user ");
13795                    builder.append(UserHandle.getUserId(callingUid));
13796                    builder.append("; this requires ");
13797                    builder.append(INTERACT_ACROSS_USERS_FULL);
13798                    if (allowMode != ALLOW_FULL_ONLY) {
13799                        builder.append(" or ");
13800                        builder.append(INTERACT_ACROSS_USERS);
13801                    }
13802                    String msg = builder.toString();
13803                    Slog.w(TAG, msg);
13804                    throw new SecurityException(msg);
13805                }
13806            }
13807        }
13808        if (!allowAll && targetUserId < 0) {
13809            throw new IllegalArgumentException(
13810                    "Call does not support special user #" + targetUserId);
13811        }
13812        return targetUserId;
13813    }
13814
13815    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13816            String className, int flags) {
13817        boolean result = false;
13818        // For apps that don't have pre-defined UIDs, check for permission
13819        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13820            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13821                if (ActivityManager.checkUidPermission(
13822                        INTERACT_ACROSS_USERS,
13823                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13824                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13825                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13826                            + " requests FLAG_SINGLE_USER, but app does not hold "
13827                            + INTERACT_ACROSS_USERS;
13828                    Slog.w(TAG, msg);
13829                    throw new SecurityException(msg);
13830                }
13831                // Permission passed
13832                result = true;
13833            }
13834        } else if ("system".equals(componentProcessName)) {
13835            result = true;
13836        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
13837                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13838            // Phone app is allowed to export singleuser providers.
13839            result = true;
13840        } else {
13841            // App with pre-defined UID, check if it's a persistent app
13842            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13843        }
13844        if (DEBUG_MU) {
13845            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13846                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13847        }
13848        return result;
13849    }
13850
13851    /**
13852     * Checks to see if the caller is in the same app as the singleton
13853     * component, or the component is in a special app. It allows special apps
13854     * to export singleton components but prevents exporting singleton
13855     * components for regular apps.
13856     */
13857    boolean isValidSingletonCall(int callingUid, int componentUid) {
13858        int componentAppId = UserHandle.getAppId(componentUid);
13859        return UserHandle.isSameApp(callingUid, componentUid)
13860                || componentAppId == Process.SYSTEM_UID
13861                || componentAppId == Process.PHONE_UID
13862                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13863                        == PackageManager.PERMISSION_GRANTED;
13864    }
13865
13866    public int bindService(IApplicationThread caller, IBinder token,
13867            Intent service, String resolvedType,
13868            IServiceConnection connection, int flags, int userId) {
13869        enforceNotIsolatedCaller("bindService");
13870        // Refuse possible leaked file descriptors
13871        if (service != null && service.hasFileDescriptors() == true) {
13872            throw new IllegalArgumentException("File descriptors passed in Intent");
13873        }
13874
13875        synchronized(this) {
13876            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13877                    connection, flags, userId);
13878        }
13879    }
13880
13881    public boolean unbindService(IServiceConnection connection) {
13882        synchronized (this) {
13883            return mServices.unbindServiceLocked(connection);
13884        }
13885    }
13886
13887    public void publishService(IBinder token, Intent intent, IBinder service) {
13888        // Refuse possible leaked file descriptors
13889        if (intent != null && intent.hasFileDescriptors() == true) {
13890            throw new IllegalArgumentException("File descriptors passed in Intent");
13891        }
13892
13893        synchronized(this) {
13894            if (!(token instanceof ServiceRecord)) {
13895                throw new IllegalArgumentException("Invalid service token");
13896            }
13897            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13898        }
13899    }
13900
13901    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13902        // Refuse possible leaked file descriptors
13903        if (intent != null && intent.hasFileDescriptors() == true) {
13904            throw new IllegalArgumentException("File descriptors passed in Intent");
13905        }
13906
13907        synchronized(this) {
13908            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13909        }
13910    }
13911
13912    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13913        synchronized(this) {
13914            if (!(token instanceof ServiceRecord)) {
13915                throw new IllegalArgumentException("Invalid service token");
13916            }
13917            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13918        }
13919    }
13920
13921    // =========================================================
13922    // BACKUP AND RESTORE
13923    // =========================================================
13924
13925    // Cause the target app to be launched if necessary and its backup agent
13926    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13927    // activity manager to announce its creation.
13928    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13929        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13930        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13931
13932        synchronized(this) {
13933            // !!! TODO: currently no check here that we're already bound
13934            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13935            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13936            synchronized (stats) {
13937                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13938            }
13939
13940            // Backup agent is now in use, its package can't be stopped.
13941            try {
13942                AppGlobals.getPackageManager().setPackageStoppedState(
13943                        app.packageName, false, UserHandle.getUserId(app.uid));
13944            } catch (RemoteException e) {
13945            } catch (IllegalArgumentException e) {
13946                Slog.w(TAG, "Failed trying to unstop package "
13947                        + app.packageName + ": " + e);
13948            }
13949
13950            BackupRecord r = new BackupRecord(ss, app, backupMode);
13951            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13952                    ? new ComponentName(app.packageName, app.backupAgentName)
13953                    : new ComponentName("android", "FullBackupAgent");
13954            // startProcessLocked() returns existing proc's record if it's already running
13955            ProcessRecord proc = startProcessLocked(app.processName, app,
13956                    false, 0, "backup", hostingName, false, false, false);
13957            if (proc == null) {
13958                Slog.e(TAG, "Unable to start backup agent process " + r);
13959                return false;
13960            }
13961
13962            r.app = proc;
13963            mBackupTarget = r;
13964            mBackupAppName = app.packageName;
13965
13966            // Try not to kill the process during backup
13967            updateOomAdjLocked(proc);
13968
13969            // If the process is already attached, schedule the creation of the backup agent now.
13970            // If it is not yet live, this will be done when it attaches to the framework.
13971            if (proc.thread != null) {
13972                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13973                try {
13974                    proc.thread.scheduleCreateBackupAgent(app,
13975                            compatibilityInfoForPackageLocked(app), backupMode);
13976                } catch (RemoteException e) {
13977                    // Will time out on the backup manager side
13978                }
13979            } else {
13980                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13981            }
13982            // Invariants: at this point, the target app process exists and the application
13983            // is either already running or in the process of coming up.  mBackupTarget and
13984            // mBackupAppName describe the app, so that when it binds back to the AM we
13985            // know that it's scheduled for a backup-agent operation.
13986        }
13987
13988        return true;
13989    }
13990
13991    @Override
13992    public void clearPendingBackup() {
13993        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13994        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13995
13996        synchronized (this) {
13997            mBackupTarget = null;
13998            mBackupAppName = null;
13999        }
14000    }
14001
14002    // A backup agent has just come up
14003    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14004        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14005                + " = " + agent);
14006
14007        synchronized(this) {
14008            if (!agentPackageName.equals(mBackupAppName)) {
14009                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14010                return;
14011            }
14012        }
14013
14014        long oldIdent = Binder.clearCallingIdentity();
14015        try {
14016            IBackupManager bm = IBackupManager.Stub.asInterface(
14017                    ServiceManager.getService(Context.BACKUP_SERVICE));
14018            bm.agentConnected(agentPackageName, agent);
14019        } catch (RemoteException e) {
14020            // can't happen; the backup manager service is local
14021        } catch (Exception e) {
14022            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14023            e.printStackTrace();
14024        } finally {
14025            Binder.restoreCallingIdentity(oldIdent);
14026        }
14027    }
14028
14029    // done with this agent
14030    public void unbindBackupAgent(ApplicationInfo appInfo) {
14031        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14032        if (appInfo == null) {
14033            Slog.w(TAG, "unbind backup agent for null app");
14034            return;
14035        }
14036
14037        synchronized(this) {
14038            try {
14039                if (mBackupAppName == null) {
14040                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14041                    return;
14042                }
14043
14044                if (!mBackupAppName.equals(appInfo.packageName)) {
14045                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14046                    return;
14047                }
14048
14049                // Not backing this app up any more; reset its OOM adjustment
14050                final ProcessRecord proc = mBackupTarget.app;
14051                updateOomAdjLocked(proc);
14052
14053                // If the app crashed during backup, 'thread' will be null here
14054                if (proc.thread != null) {
14055                    try {
14056                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14057                                compatibilityInfoForPackageLocked(appInfo));
14058                    } catch (Exception e) {
14059                        Slog.e(TAG, "Exception when unbinding backup agent:");
14060                        e.printStackTrace();
14061                    }
14062                }
14063            } finally {
14064                mBackupTarget = null;
14065                mBackupAppName = null;
14066            }
14067        }
14068    }
14069    // =========================================================
14070    // BROADCASTS
14071    // =========================================================
14072
14073    private final List getStickiesLocked(String action, IntentFilter filter,
14074            List cur, int userId) {
14075        final ContentResolver resolver = mContext.getContentResolver();
14076        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14077        if (stickies == null) {
14078            return cur;
14079        }
14080        final ArrayList<Intent> list = stickies.get(action);
14081        if (list == null) {
14082            return cur;
14083        }
14084        int N = list.size();
14085        for (int i=0; i<N; i++) {
14086            Intent intent = list.get(i);
14087            if (filter.match(resolver, intent, true, TAG) >= 0) {
14088                if (cur == null) {
14089                    cur = new ArrayList<Intent>();
14090                }
14091                cur.add(intent);
14092            }
14093        }
14094        return cur;
14095    }
14096
14097    boolean isPendingBroadcastProcessLocked(int pid) {
14098        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14099                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14100    }
14101
14102    void skipPendingBroadcastLocked(int pid) {
14103            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14104            for (BroadcastQueue queue : mBroadcastQueues) {
14105                queue.skipPendingBroadcastLocked(pid);
14106            }
14107    }
14108
14109    // The app just attached; send any pending broadcasts that it should receive
14110    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14111        boolean didSomething = false;
14112        for (BroadcastQueue queue : mBroadcastQueues) {
14113            didSomething |= queue.sendPendingBroadcastsLocked(app);
14114        }
14115        return didSomething;
14116    }
14117
14118    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14119            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14120        enforceNotIsolatedCaller("registerReceiver");
14121        int callingUid;
14122        int callingPid;
14123        synchronized(this) {
14124            ProcessRecord callerApp = null;
14125            if (caller != null) {
14126                callerApp = getRecordForAppLocked(caller);
14127                if (callerApp == null) {
14128                    throw new SecurityException(
14129                            "Unable to find app for caller " + caller
14130                            + " (pid=" + Binder.getCallingPid()
14131                            + ") when registering receiver " + receiver);
14132                }
14133                if (callerApp.info.uid != Process.SYSTEM_UID &&
14134                        !callerApp.pkgList.containsKey(callerPackage) &&
14135                        !"android".equals(callerPackage)) {
14136                    throw new SecurityException("Given caller package " + callerPackage
14137                            + " is not running in process " + callerApp);
14138                }
14139                callingUid = callerApp.info.uid;
14140                callingPid = callerApp.pid;
14141            } else {
14142                callerPackage = null;
14143                callingUid = Binder.getCallingUid();
14144                callingPid = Binder.getCallingPid();
14145            }
14146
14147            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14148                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14149
14150            List allSticky = null;
14151
14152            // Look for any matching sticky broadcasts...
14153            Iterator actions = filter.actionsIterator();
14154            if (actions != null) {
14155                while (actions.hasNext()) {
14156                    String action = (String)actions.next();
14157                    allSticky = getStickiesLocked(action, filter, allSticky,
14158                            UserHandle.USER_ALL);
14159                    allSticky = getStickiesLocked(action, filter, allSticky,
14160                            UserHandle.getUserId(callingUid));
14161                }
14162            } else {
14163                allSticky = getStickiesLocked(null, filter, allSticky,
14164                        UserHandle.USER_ALL);
14165                allSticky = getStickiesLocked(null, filter, allSticky,
14166                        UserHandle.getUserId(callingUid));
14167            }
14168
14169            // The first sticky in the list is returned directly back to
14170            // the client.
14171            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14172
14173            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14174                    + ": " + sticky);
14175
14176            if (receiver == null) {
14177                return sticky;
14178            }
14179
14180            ReceiverList rl
14181                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14182            if (rl == null) {
14183                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14184                        userId, receiver);
14185                if (rl.app != null) {
14186                    rl.app.receivers.add(rl);
14187                } else {
14188                    try {
14189                        receiver.asBinder().linkToDeath(rl, 0);
14190                    } catch (RemoteException e) {
14191                        return sticky;
14192                    }
14193                    rl.linkedToDeath = true;
14194                }
14195                mRegisteredReceivers.put(receiver.asBinder(), rl);
14196            } else if (rl.uid != callingUid) {
14197                throw new IllegalArgumentException(
14198                        "Receiver requested to register for uid " + callingUid
14199                        + " was previously registered for uid " + rl.uid);
14200            } else if (rl.pid != callingPid) {
14201                throw new IllegalArgumentException(
14202                        "Receiver requested to register for pid " + callingPid
14203                        + " was previously registered for pid " + rl.pid);
14204            } else if (rl.userId != userId) {
14205                throw new IllegalArgumentException(
14206                        "Receiver requested to register for user " + userId
14207                        + " was previously registered for user " + rl.userId);
14208            }
14209            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14210                    permission, callingUid, userId);
14211            rl.add(bf);
14212            if (!bf.debugCheck()) {
14213                Slog.w(TAG, "==> For Dynamic broadast");
14214            }
14215            mReceiverResolver.addFilter(bf);
14216
14217            // Enqueue broadcasts for all existing stickies that match
14218            // this filter.
14219            if (allSticky != null) {
14220                ArrayList receivers = new ArrayList();
14221                receivers.add(bf);
14222
14223                int N = allSticky.size();
14224                for (int i=0; i<N; i++) {
14225                    Intent intent = (Intent)allSticky.get(i);
14226                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14227                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14228                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14229                            null, null, false, true, true, -1);
14230                    queue.enqueueParallelBroadcastLocked(r);
14231                    queue.scheduleBroadcastsLocked();
14232                }
14233            }
14234
14235            return sticky;
14236        }
14237    }
14238
14239    public void unregisterReceiver(IIntentReceiver receiver) {
14240        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14241
14242        final long origId = Binder.clearCallingIdentity();
14243        try {
14244            boolean doTrim = false;
14245
14246            synchronized(this) {
14247                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14248                if (rl != null) {
14249                    if (rl.curBroadcast != null) {
14250                        BroadcastRecord r = rl.curBroadcast;
14251                        final boolean doNext = finishReceiverLocked(
14252                                receiver.asBinder(), r.resultCode, r.resultData,
14253                                r.resultExtras, r.resultAbort);
14254                        if (doNext) {
14255                            doTrim = true;
14256                            r.queue.processNextBroadcast(false);
14257                        }
14258                    }
14259
14260                    if (rl.app != null) {
14261                        rl.app.receivers.remove(rl);
14262                    }
14263                    removeReceiverLocked(rl);
14264                    if (rl.linkedToDeath) {
14265                        rl.linkedToDeath = false;
14266                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14267                    }
14268                }
14269            }
14270
14271            // If we actually concluded any broadcasts, we might now be able
14272            // to trim the recipients' apps from our working set
14273            if (doTrim) {
14274                trimApplications();
14275                return;
14276            }
14277
14278        } finally {
14279            Binder.restoreCallingIdentity(origId);
14280        }
14281    }
14282
14283    void removeReceiverLocked(ReceiverList rl) {
14284        mRegisteredReceivers.remove(rl.receiver.asBinder());
14285        int N = rl.size();
14286        for (int i=0; i<N; i++) {
14287            mReceiverResolver.removeFilter(rl.get(i));
14288        }
14289    }
14290
14291    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14292        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14293            ProcessRecord r = mLruProcesses.get(i);
14294            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14295                try {
14296                    r.thread.dispatchPackageBroadcast(cmd, packages);
14297                } catch (RemoteException ex) {
14298                }
14299            }
14300        }
14301    }
14302
14303    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14304            int[] users) {
14305        List<ResolveInfo> receivers = null;
14306        try {
14307            HashSet<ComponentName> singleUserReceivers = null;
14308            boolean scannedFirstReceivers = false;
14309            for (int user : users) {
14310                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14311                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14312                if (user != 0 && newReceivers != null) {
14313                    // If this is not the primary user, we need to check for
14314                    // any receivers that should be filtered out.
14315                    for (int i=0; i<newReceivers.size(); i++) {
14316                        ResolveInfo ri = newReceivers.get(i);
14317                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14318                            newReceivers.remove(i);
14319                            i--;
14320                        }
14321                    }
14322                }
14323                if (newReceivers != null && newReceivers.size() == 0) {
14324                    newReceivers = null;
14325                }
14326                if (receivers == null) {
14327                    receivers = newReceivers;
14328                } else if (newReceivers != null) {
14329                    // We need to concatenate the additional receivers
14330                    // found with what we have do far.  This would be easy,
14331                    // but we also need to de-dup any receivers that are
14332                    // singleUser.
14333                    if (!scannedFirstReceivers) {
14334                        // Collect any single user receivers we had already retrieved.
14335                        scannedFirstReceivers = true;
14336                        for (int i=0; i<receivers.size(); i++) {
14337                            ResolveInfo ri = receivers.get(i);
14338                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14339                                ComponentName cn = new ComponentName(
14340                                        ri.activityInfo.packageName, ri.activityInfo.name);
14341                                if (singleUserReceivers == null) {
14342                                    singleUserReceivers = new HashSet<ComponentName>();
14343                                }
14344                                singleUserReceivers.add(cn);
14345                            }
14346                        }
14347                    }
14348                    // Add the new results to the existing results, tracking
14349                    // and de-dupping single user receivers.
14350                    for (int i=0; i<newReceivers.size(); i++) {
14351                        ResolveInfo ri = newReceivers.get(i);
14352                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14353                            ComponentName cn = new ComponentName(
14354                                    ri.activityInfo.packageName, ri.activityInfo.name);
14355                            if (singleUserReceivers == null) {
14356                                singleUserReceivers = new HashSet<ComponentName>();
14357                            }
14358                            if (!singleUserReceivers.contains(cn)) {
14359                                singleUserReceivers.add(cn);
14360                                receivers.add(ri);
14361                            }
14362                        } else {
14363                            receivers.add(ri);
14364                        }
14365                    }
14366                }
14367            }
14368        } catch (RemoteException ex) {
14369            // pm is in same process, this will never happen.
14370        }
14371        return receivers;
14372    }
14373
14374    private final int broadcastIntentLocked(ProcessRecord callerApp,
14375            String callerPackage, Intent intent, String resolvedType,
14376            IIntentReceiver resultTo, int resultCode, String resultData,
14377            Bundle map, String requiredPermission, int appOp,
14378            boolean ordered, boolean sticky, int callingPid, int callingUid,
14379            int userId) {
14380        intent = new Intent(intent);
14381
14382        // By default broadcasts do not go to stopped apps.
14383        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14384
14385        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14386            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14387            + " ordered=" + ordered + " userid=" + userId);
14388        if ((resultTo != null) && !ordered) {
14389            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14390        }
14391
14392        userId = handleIncomingUser(callingPid, callingUid, userId,
14393                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14394
14395        // Make sure that the user who is receiving this broadcast is started.
14396        // If not, we will just skip it.
14397
14398
14399        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14400            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14401                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14402                Slog.w(TAG, "Skipping broadcast of " + intent
14403                        + ": user " + userId + " is stopped");
14404                return ActivityManager.BROADCAST_SUCCESS;
14405            }
14406        }
14407
14408        /*
14409         * Prevent non-system code (defined here to be non-persistent
14410         * processes) from sending protected broadcasts.
14411         */
14412        int callingAppId = UserHandle.getAppId(callingUid);
14413        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14414            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14415            || callingAppId == Process.NFC_UID || callingUid == 0) {
14416            // Always okay.
14417        } else if (callerApp == null || !callerApp.persistent) {
14418            try {
14419                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14420                        intent.getAction())) {
14421                    String msg = "Permission Denial: not allowed to send broadcast "
14422                            + intent.getAction() + " from pid="
14423                            + callingPid + ", uid=" + callingUid;
14424                    Slog.w(TAG, msg);
14425                    throw new SecurityException(msg);
14426                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14427                    // Special case for compatibility: we don't want apps to send this,
14428                    // but historically it has not been protected and apps may be using it
14429                    // to poke their own app widget.  So, instead of making it protected,
14430                    // just limit it to the caller.
14431                    if (callerApp == null) {
14432                        String msg = "Permission Denial: not allowed to send broadcast "
14433                                + intent.getAction() + " from unknown caller.";
14434                        Slog.w(TAG, msg);
14435                        throw new SecurityException(msg);
14436                    } else if (intent.getComponent() != null) {
14437                        // They are good enough to send to an explicit component...  verify
14438                        // it is being sent to the calling app.
14439                        if (!intent.getComponent().getPackageName().equals(
14440                                callerApp.info.packageName)) {
14441                            String msg = "Permission Denial: not allowed to send broadcast "
14442                                    + intent.getAction() + " to "
14443                                    + intent.getComponent().getPackageName() + " from "
14444                                    + callerApp.info.packageName;
14445                            Slog.w(TAG, msg);
14446                            throw new SecurityException(msg);
14447                        }
14448                    } else {
14449                        // Limit broadcast to their own package.
14450                        intent.setPackage(callerApp.info.packageName);
14451                    }
14452                }
14453            } catch (RemoteException e) {
14454                Slog.w(TAG, "Remote exception", e);
14455                return ActivityManager.BROADCAST_SUCCESS;
14456            }
14457        }
14458
14459        // Handle special intents: if this broadcast is from the package
14460        // manager about a package being removed, we need to remove all of
14461        // its activities from the history stack.
14462        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14463                intent.getAction());
14464        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14465                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14466                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14467                || uidRemoved) {
14468            if (checkComponentPermission(
14469                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14470                    callingPid, callingUid, -1, true)
14471                    == PackageManager.PERMISSION_GRANTED) {
14472                if (uidRemoved) {
14473                    final Bundle intentExtras = intent.getExtras();
14474                    final int uid = intentExtras != null
14475                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14476                    if (uid >= 0) {
14477                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14478                        synchronized (bs) {
14479                            bs.removeUidStatsLocked(uid);
14480                        }
14481                        mAppOpsService.uidRemoved(uid);
14482                    }
14483                } else {
14484                    // If resources are unavailable just force stop all
14485                    // those packages and flush the attribute cache as well.
14486                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14487                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14488                        if (list != null && (list.length > 0)) {
14489                            for (String pkg : list) {
14490                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14491                                        "storage unmount");
14492                            }
14493                            sendPackageBroadcastLocked(
14494                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14495                        }
14496                    } else {
14497                        Uri data = intent.getData();
14498                        String ssp;
14499                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14500                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14501                                    intent.getAction());
14502                            boolean fullUninstall = removed &&
14503                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14504                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14505                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14506                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14507                                        false, fullUninstall, userId,
14508                                        removed ? "pkg removed" : "pkg changed");
14509                            }
14510                            if (removed) {
14511                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14512                                        new String[] {ssp}, userId);
14513                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14514                                    mAppOpsService.packageRemoved(
14515                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14516
14517                                    // Remove all permissions granted from/to this package
14518                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14519                                }
14520                            }
14521                        }
14522                    }
14523                }
14524            } else {
14525                String msg = "Permission Denial: " + intent.getAction()
14526                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14527                        + ", uid=" + callingUid + ")"
14528                        + " requires "
14529                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14530                Slog.w(TAG, msg);
14531                throw new SecurityException(msg);
14532            }
14533
14534        // Special case for adding a package: by default turn on compatibility
14535        // mode.
14536        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14537            Uri data = intent.getData();
14538            String ssp;
14539            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14540                mCompatModePackages.handlePackageAddedLocked(ssp,
14541                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14542            }
14543        }
14544
14545        /*
14546         * If this is the time zone changed action, queue up a message that will reset the timezone
14547         * of all currently running processes. This message will get queued up before the broadcast
14548         * happens.
14549         */
14550        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14551            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14552        }
14553
14554        /*
14555         * If the user set the time, let all running processes know.
14556         */
14557        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14558            final int is24Hour = intent.getBooleanExtra(
14559                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14560            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14561        }
14562
14563        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14564            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14565        }
14566
14567        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14568            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14569            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14570        }
14571
14572        // Add to the sticky list if requested.
14573        if (sticky) {
14574            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14575                    callingPid, callingUid)
14576                    != PackageManager.PERMISSION_GRANTED) {
14577                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14578                        + callingPid + ", uid=" + callingUid
14579                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14580                Slog.w(TAG, msg);
14581                throw new SecurityException(msg);
14582            }
14583            if (requiredPermission != null) {
14584                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14585                        + " and enforce permission " + requiredPermission);
14586                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14587            }
14588            if (intent.getComponent() != null) {
14589                throw new SecurityException(
14590                        "Sticky broadcasts can't target a specific component");
14591            }
14592            // We use userId directly here, since the "all" target is maintained
14593            // as a separate set of sticky broadcasts.
14594            if (userId != UserHandle.USER_ALL) {
14595                // But first, if this is not a broadcast to all users, then
14596                // make sure it doesn't conflict with an existing broadcast to
14597                // all users.
14598                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14599                        UserHandle.USER_ALL);
14600                if (stickies != null) {
14601                    ArrayList<Intent> list = stickies.get(intent.getAction());
14602                    if (list != null) {
14603                        int N = list.size();
14604                        int i;
14605                        for (i=0; i<N; i++) {
14606                            if (intent.filterEquals(list.get(i))) {
14607                                throw new IllegalArgumentException(
14608                                        "Sticky broadcast " + intent + " for user "
14609                                        + userId + " conflicts with existing global broadcast");
14610                            }
14611                        }
14612                    }
14613                }
14614            }
14615            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14616            if (stickies == null) {
14617                stickies = new ArrayMap<String, ArrayList<Intent>>();
14618                mStickyBroadcasts.put(userId, stickies);
14619            }
14620            ArrayList<Intent> list = stickies.get(intent.getAction());
14621            if (list == null) {
14622                list = new ArrayList<Intent>();
14623                stickies.put(intent.getAction(), list);
14624            }
14625            int N = list.size();
14626            int i;
14627            for (i=0; i<N; i++) {
14628                if (intent.filterEquals(list.get(i))) {
14629                    // This sticky already exists, replace it.
14630                    list.set(i, new Intent(intent));
14631                    break;
14632                }
14633            }
14634            if (i >= N) {
14635                list.add(new Intent(intent));
14636            }
14637        }
14638
14639        int[] users;
14640        if (userId == UserHandle.USER_ALL) {
14641            // Caller wants broadcast to go to all started users.
14642            users = mStartedUserArray;
14643        } else {
14644            // Caller wants broadcast to go to one specific user.
14645            users = new int[] {userId};
14646        }
14647
14648        // Figure out who all will receive this broadcast.
14649        List receivers = null;
14650        List<BroadcastFilter> registeredReceivers = null;
14651        // Need to resolve the intent to interested receivers...
14652        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14653                 == 0) {
14654            receivers = collectReceiverComponents(intent, resolvedType, users);
14655        }
14656        if (intent.getComponent() == null) {
14657            registeredReceivers = mReceiverResolver.queryIntent(intent,
14658                    resolvedType, false, userId);
14659        }
14660
14661        final boolean replacePending =
14662                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14663
14664        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14665                + " replacePending=" + replacePending);
14666
14667        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14668        if (!ordered && NR > 0) {
14669            // If we are not serializing this broadcast, then send the
14670            // registered receivers separately so they don't wait for the
14671            // components to be launched.
14672            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14673            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14674                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14675                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14676                    ordered, sticky, false, userId);
14677            if (DEBUG_BROADCAST) Slog.v(
14678                    TAG, "Enqueueing parallel broadcast " + r);
14679            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14680            if (!replaced) {
14681                queue.enqueueParallelBroadcastLocked(r);
14682                queue.scheduleBroadcastsLocked();
14683            }
14684            registeredReceivers = null;
14685            NR = 0;
14686        }
14687
14688        // Merge into one list.
14689        int ir = 0;
14690        if (receivers != null) {
14691            // A special case for PACKAGE_ADDED: do not allow the package
14692            // being added to see this broadcast.  This prevents them from
14693            // using this as a back door to get run as soon as they are
14694            // installed.  Maybe in the future we want to have a special install
14695            // broadcast or such for apps, but we'd like to deliberately make
14696            // this decision.
14697            String skipPackages[] = null;
14698            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14699                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14700                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14701                Uri data = intent.getData();
14702                if (data != null) {
14703                    String pkgName = data.getSchemeSpecificPart();
14704                    if (pkgName != null) {
14705                        skipPackages = new String[] { pkgName };
14706                    }
14707                }
14708            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14709                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14710            }
14711            if (skipPackages != null && (skipPackages.length > 0)) {
14712                for (String skipPackage : skipPackages) {
14713                    if (skipPackage != null) {
14714                        int NT = receivers.size();
14715                        for (int it=0; it<NT; it++) {
14716                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14717                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14718                                receivers.remove(it);
14719                                it--;
14720                                NT--;
14721                            }
14722                        }
14723                    }
14724                }
14725            }
14726
14727            int NT = receivers != null ? receivers.size() : 0;
14728            int it = 0;
14729            ResolveInfo curt = null;
14730            BroadcastFilter curr = null;
14731            while (it < NT && ir < NR) {
14732                if (curt == null) {
14733                    curt = (ResolveInfo)receivers.get(it);
14734                }
14735                if (curr == null) {
14736                    curr = registeredReceivers.get(ir);
14737                }
14738                if (curr.getPriority() >= curt.priority) {
14739                    // Insert this broadcast record into the final list.
14740                    receivers.add(it, curr);
14741                    ir++;
14742                    curr = null;
14743                    it++;
14744                    NT++;
14745                } else {
14746                    // Skip to the next ResolveInfo in the final list.
14747                    it++;
14748                    curt = null;
14749                }
14750            }
14751        }
14752        while (ir < NR) {
14753            if (receivers == null) {
14754                receivers = new ArrayList();
14755            }
14756            receivers.add(registeredReceivers.get(ir));
14757            ir++;
14758        }
14759
14760        if ((receivers != null && receivers.size() > 0)
14761                || resultTo != null) {
14762            BroadcastQueue queue = broadcastQueueForIntent(intent);
14763            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14764                    callerPackage, callingPid, callingUid, resolvedType,
14765                    requiredPermission, appOp, receivers, resultTo, resultCode,
14766                    resultData, map, ordered, sticky, false, userId);
14767            if (DEBUG_BROADCAST) Slog.v(
14768                    TAG, "Enqueueing ordered broadcast " + r
14769                    + ": prev had " + queue.mOrderedBroadcasts.size());
14770            if (DEBUG_BROADCAST) {
14771                int seq = r.intent.getIntExtra("seq", -1);
14772                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14773            }
14774            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14775            if (!replaced) {
14776                queue.enqueueOrderedBroadcastLocked(r);
14777                queue.scheduleBroadcastsLocked();
14778            }
14779        }
14780
14781        return ActivityManager.BROADCAST_SUCCESS;
14782    }
14783
14784    final Intent verifyBroadcastLocked(Intent intent) {
14785        // Refuse possible leaked file descriptors
14786        if (intent != null && intent.hasFileDescriptors() == true) {
14787            throw new IllegalArgumentException("File descriptors passed in Intent");
14788        }
14789
14790        int flags = intent.getFlags();
14791
14792        if (!mProcessesReady) {
14793            // if the caller really truly claims to know what they're doing, go
14794            // ahead and allow the broadcast without launching any receivers
14795            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14796                intent = new Intent(intent);
14797                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14798            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14799                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14800                        + " before boot completion");
14801                throw new IllegalStateException("Cannot broadcast before boot completed");
14802            }
14803        }
14804
14805        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14806            throw new IllegalArgumentException(
14807                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14808        }
14809
14810        return intent;
14811    }
14812
14813    public final int broadcastIntent(IApplicationThread caller,
14814            Intent intent, String resolvedType, IIntentReceiver resultTo,
14815            int resultCode, String resultData, Bundle map,
14816            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14817        enforceNotIsolatedCaller("broadcastIntent");
14818        synchronized(this) {
14819            intent = verifyBroadcastLocked(intent);
14820
14821            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14822            final int callingPid = Binder.getCallingPid();
14823            final int callingUid = Binder.getCallingUid();
14824            final long origId = Binder.clearCallingIdentity();
14825            int res = broadcastIntentLocked(callerApp,
14826                    callerApp != null ? callerApp.info.packageName : null,
14827                    intent, resolvedType, resultTo,
14828                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14829                    callingPid, callingUid, userId);
14830            Binder.restoreCallingIdentity(origId);
14831            return res;
14832        }
14833    }
14834
14835    int broadcastIntentInPackage(String packageName, int uid,
14836            Intent intent, String resolvedType, IIntentReceiver resultTo,
14837            int resultCode, String resultData, Bundle map,
14838            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14839        synchronized(this) {
14840            intent = verifyBroadcastLocked(intent);
14841
14842            final long origId = Binder.clearCallingIdentity();
14843            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14844                    resultTo, resultCode, resultData, map, requiredPermission,
14845                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14846            Binder.restoreCallingIdentity(origId);
14847            return res;
14848        }
14849    }
14850
14851    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14852        // Refuse possible leaked file descriptors
14853        if (intent != null && intent.hasFileDescriptors() == true) {
14854            throw new IllegalArgumentException("File descriptors passed in Intent");
14855        }
14856
14857        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14858                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14859
14860        synchronized(this) {
14861            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14862                    != PackageManager.PERMISSION_GRANTED) {
14863                String msg = "Permission Denial: unbroadcastIntent() from pid="
14864                        + Binder.getCallingPid()
14865                        + ", uid=" + Binder.getCallingUid()
14866                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14867                Slog.w(TAG, msg);
14868                throw new SecurityException(msg);
14869            }
14870            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14871            if (stickies != null) {
14872                ArrayList<Intent> list = stickies.get(intent.getAction());
14873                if (list != null) {
14874                    int N = list.size();
14875                    int i;
14876                    for (i=0; i<N; i++) {
14877                        if (intent.filterEquals(list.get(i))) {
14878                            list.remove(i);
14879                            break;
14880                        }
14881                    }
14882                    if (list.size() <= 0) {
14883                        stickies.remove(intent.getAction());
14884                    }
14885                }
14886                if (stickies.size() <= 0) {
14887                    mStickyBroadcasts.remove(userId);
14888                }
14889            }
14890        }
14891    }
14892
14893    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14894            String resultData, Bundle resultExtras, boolean resultAbort) {
14895        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14896        if (r == null) {
14897            Slog.w(TAG, "finishReceiver called but not found on queue");
14898            return false;
14899        }
14900
14901        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14902    }
14903
14904    void backgroundServicesFinishedLocked(int userId) {
14905        for (BroadcastQueue queue : mBroadcastQueues) {
14906            queue.backgroundServicesFinishedLocked(userId);
14907        }
14908    }
14909
14910    public void finishReceiver(IBinder who, int resultCode, String resultData,
14911            Bundle resultExtras, boolean resultAbort) {
14912        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14913
14914        // Refuse possible leaked file descriptors
14915        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14916            throw new IllegalArgumentException("File descriptors passed in Bundle");
14917        }
14918
14919        final long origId = Binder.clearCallingIdentity();
14920        try {
14921            boolean doNext = false;
14922            BroadcastRecord r;
14923
14924            synchronized(this) {
14925                r = broadcastRecordForReceiverLocked(who);
14926                if (r != null) {
14927                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14928                        resultData, resultExtras, resultAbort, true);
14929                }
14930            }
14931
14932            if (doNext) {
14933                r.queue.processNextBroadcast(false);
14934            }
14935            trimApplications();
14936        } finally {
14937            Binder.restoreCallingIdentity(origId);
14938        }
14939    }
14940
14941    // =========================================================
14942    // INSTRUMENTATION
14943    // =========================================================
14944
14945    public boolean startInstrumentation(ComponentName className,
14946            String profileFile, int flags, Bundle arguments,
14947            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14948            int userId, String abiOverride) {
14949        enforceNotIsolatedCaller("startInstrumentation");
14950        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14951                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14952        // Refuse possible leaked file descriptors
14953        if (arguments != null && arguments.hasFileDescriptors()) {
14954            throw new IllegalArgumentException("File descriptors passed in Bundle");
14955        }
14956
14957        synchronized(this) {
14958            InstrumentationInfo ii = null;
14959            ApplicationInfo ai = null;
14960            try {
14961                ii = mContext.getPackageManager().getInstrumentationInfo(
14962                    className, STOCK_PM_FLAGS);
14963                ai = AppGlobals.getPackageManager().getApplicationInfo(
14964                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14965            } catch (PackageManager.NameNotFoundException e) {
14966            } catch (RemoteException e) {
14967            }
14968            if (ii == null) {
14969                reportStartInstrumentationFailure(watcher, className,
14970                        "Unable to find instrumentation info for: " + className);
14971                return false;
14972            }
14973            if (ai == null) {
14974                reportStartInstrumentationFailure(watcher, className,
14975                        "Unable to find instrumentation target package: " + ii.targetPackage);
14976                return false;
14977            }
14978
14979            int match = mContext.getPackageManager().checkSignatures(
14980                    ii.targetPackage, ii.packageName);
14981            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14982                String msg = "Permission Denial: starting instrumentation "
14983                        + className + " from pid="
14984                        + Binder.getCallingPid()
14985                        + ", uid=" + Binder.getCallingPid()
14986                        + " not allowed because package " + ii.packageName
14987                        + " does not have a signature matching the target "
14988                        + ii.targetPackage;
14989                reportStartInstrumentationFailure(watcher, className, msg);
14990                throw new SecurityException(msg);
14991            }
14992
14993            final long origId = Binder.clearCallingIdentity();
14994            // Instrumentation can kill and relaunch even persistent processes
14995            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14996                    "start instr");
14997            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14998            app.instrumentationClass = className;
14999            app.instrumentationInfo = ai;
15000            app.instrumentationProfileFile = profileFile;
15001            app.instrumentationArguments = arguments;
15002            app.instrumentationWatcher = watcher;
15003            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15004            app.instrumentationResultClass = className;
15005            Binder.restoreCallingIdentity(origId);
15006        }
15007
15008        return true;
15009    }
15010
15011    /**
15012     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15013     * error to the logs, but if somebody is watching, send the report there too.  This enables
15014     * the "am" command to report errors with more information.
15015     *
15016     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15017     * @param cn The component name of the instrumentation.
15018     * @param report The error report.
15019     */
15020    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15021            ComponentName cn, String report) {
15022        Slog.w(TAG, report);
15023        try {
15024            if (watcher != null) {
15025                Bundle results = new Bundle();
15026                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15027                results.putString("Error", report);
15028                watcher.instrumentationStatus(cn, -1, results);
15029            }
15030        } catch (RemoteException e) {
15031            Slog.w(TAG, e);
15032        }
15033    }
15034
15035    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15036        if (app.instrumentationWatcher != null) {
15037            try {
15038                // NOTE:  IInstrumentationWatcher *must* be oneway here
15039                app.instrumentationWatcher.instrumentationFinished(
15040                    app.instrumentationClass,
15041                    resultCode,
15042                    results);
15043            } catch (RemoteException e) {
15044            }
15045        }
15046        if (app.instrumentationUiAutomationConnection != null) {
15047            try {
15048                app.instrumentationUiAutomationConnection.shutdown();
15049            } catch (RemoteException re) {
15050                /* ignore */
15051            }
15052            // Only a UiAutomation can set this flag and now that
15053            // it is finished we make sure it is reset to its default.
15054            mUserIsMonkey = false;
15055        }
15056        app.instrumentationWatcher = null;
15057        app.instrumentationUiAutomationConnection = null;
15058        app.instrumentationClass = null;
15059        app.instrumentationInfo = null;
15060        app.instrumentationProfileFile = null;
15061        app.instrumentationArguments = null;
15062
15063        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15064                "finished inst");
15065    }
15066
15067    public void finishInstrumentation(IApplicationThread target,
15068            int resultCode, Bundle results) {
15069        int userId = UserHandle.getCallingUserId();
15070        // Refuse possible leaked file descriptors
15071        if (results != null && results.hasFileDescriptors()) {
15072            throw new IllegalArgumentException("File descriptors passed in Intent");
15073        }
15074
15075        synchronized(this) {
15076            ProcessRecord app = getRecordForAppLocked(target);
15077            if (app == null) {
15078                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15079                return;
15080            }
15081            final long origId = Binder.clearCallingIdentity();
15082            finishInstrumentationLocked(app, resultCode, results);
15083            Binder.restoreCallingIdentity(origId);
15084        }
15085    }
15086
15087    // =========================================================
15088    // CONFIGURATION
15089    // =========================================================
15090
15091    public ConfigurationInfo getDeviceConfigurationInfo() {
15092        ConfigurationInfo config = new ConfigurationInfo();
15093        synchronized (this) {
15094            config.reqTouchScreen = mConfiguration.touchscreen;
15095            config.reqKeyboardType = mConfiguration.keyboard;
15096            config.reqNavigation = mConfiguration.navigation;
15097            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15098                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15099                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15100            }
15101            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15102                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15103                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15104            }
15105            config.reqGlEsVersion = GL_ES_VERSION;
15106        }
15107        return config;
15108    }
15109
15110    ActivityStack getFocusedStack() {
15111        return mStackSupervisor.getFocusedStack();
15112    }
15113
15114    public Configuration getConfiguration() {
15115        Configuration ci;
15116        synchronized(this) {
15117            ci = new Configuration(mConfiguration);
15118        }
15119        return ci;
15120    }
15121
15122    public void updatePersistentConfiguration(Configuration values) {
15123        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15124                "updateConfiguration()");
15125        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15126                "updateConfiguration()");
15127        if (values == null) {
15128            throw new NullPointerException("Configuration must not be null");
15129        }
15130
15131        synchronized(this) {
15132            final long origId = Binder.clearCallingIdentity();
15133            updateConfigurationLocked(values, null, true, false);
15134            Binder.restoreCallingIdentity(origId);
15135        }
15136    }
15137
15138    public void updateConfiguration(Configuration values) {
15139        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15140                "updateConfiguration()");
15141
15142        synchronized(this) {
15143            if (values == null && mWindowManager != null) {
15144                // sentinel: fetch the current configuration from the window manager
15145                values = mWindowManager.computeNewConfiguration();
15146            }
15147
15148            if (mWindowManager != null) {
15149                mProcessList.applyDisplaySize(mWindowManager);
15150            }
15151
15152            final long origId = Binder.clearCallingIdentity();
15153            if (values != null) {
15154                Settings.System.clearConfiguration(values);
15155            }
15156            updateConfigurationLocked(values, null, false, false);
15157            Binder.restoreCallingIdentity(origId);
15158        }
15159    }
15160
15161    /**
15162     * Do either or both things: (1) change the current configuration, and (2)
15163     * make sure the given activity is running with the (now) current
15164     * configuration.  Returns true if the activity has been left running, or
15165     * false if <var>starting</var> is being destroyed to match the new
15166     * configuration.
15167     * @param persistent TODO
15168     */
15169    boolean updateConfigurationLocked(Configuration values,
15170            ActivityRecord starting, boolean persistent, boolean initLocale) {
15171        int changes = 0;
15172
15173        if (values != null) {
15174            Configuration newConfig = new Configuration(mConfiguration);
15175            changes = newConfig.updateFrom(values);
15176            if (changes != 0) {
15177                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15178                    Slog.i(TAG, "Updating configuration to: " + values);
15179                }
15180
15181                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15182
15183                if (values.locale != null && !initLocale) {
15184                    saveLocaleLocked(values.locale,
15185                                     !values.locale.equals(mConfiguration.locale),
15186                                     values.userSetLocale);
15187                }
15188
15189                mConfigurationSeq++;
15190                if (mConfigurationSeq <= 0) {
15191                    mConfigurationSeq = 1;
15192                }
15193                newConfig.seq = mConfigurationSeq;
15194                mConfiguration = newConfig;
15195                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15196                //mUsageStatsService.noteStartConfig(newConfig);
15197
15198                final Configuration configCopy = new Configuration(mConfiguration);
15199
15200                // TODO: If our config changes, should we auto dismiss any currently
15201                // showing dialogs?
15202                mShowDialogs = shouldShowDialogs(newConfig);
15203
15204                AttributeCache ac = AttributeCache.instance();
15205                if (ac != null) {
15206                    ac.updateConfiguration(configCopy);
15207                }
15208
15209                // Make sure all resources in our process are updated
15210                // right now, so that anyone who is going to retrieve
15211                // resource values after we return will be sure to get
15212                // the new ones.  This is especially important during
15213                // boot, where the first config change needs to guarantee
15214                // all resources have that config before following boot
15215                // code is executed.
15216                mSystemThread.applyConfigurationToResources(configCopy);
15217
15218                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15219                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15220                    msg.obj = new Configuration(configCopy);
15221                    mHandler.sendMessage(msg);
15222                }
15223
15224                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15225                    ProcessRecord app = mLruProcesses.get(i);
15226                    try {
15227                        if (app.thread != null) {
15228                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15229                                    + app.processName + " new config " + mConfiguration);
15230                            app.thread.scheduleConfigurationChanged(configCopy);
15231                        }
15232                    } catch (Exception e) {
15233                    }
15234                }
15235                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15236                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15237                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15238                        | Intent.FLAG_RECEIVER_FOREGROUND);
15239                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15240                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15241                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15242                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15243                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15244                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15245                    broadcastIntentLocked(null, null, intent,
15246                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15247                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15248                }
15249            }
15250        }
15251
15252        boolean kept = true;
15253        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15254        // mainStack is null during startup.
15255        if (mainStack != null) {
15256            if (changes != 0 && starting == null) {
15257                // If the configuration changed, and the caller is not already
15258                // in the process of starting an activity, then find the top
15259                // activity to check if its configuration needs to change.
15260                starting = mainStack.topRunningActivityLocked(null);
15261            }
15262
15263            if (starting != null) {
15264                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15265                // And we need to make sure at this point that all other activities
15266                // are made visible with the correct configuration.
15267                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15268            }
15269        }
15270
15271        if (values != null && mWindowManager != null) {
15272            mWindowManager.setNewConfiguration(mConfiguration);
15273        }
15274
15275        return kept;
15276    }
15277
15278    /**
15279     * Decide based on the configuration whether we should shouw the ANR,
15280     * crash, etc dialogs.  The idea is that if there is no affordnace to
15281     * press the on-screen buttons, we shouldn't show the dialog.
15282     *
15283     * A thought: SystemUI might also want to get told about this, the Power
15284     * dialog / global actions also might want different behaviors.
15285     */
15286    private static final boolean shouldShowDialogs(Configuration config) {
15287        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15288                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15289    }
15290
15291    /**
15292     * Save the locale.  You must be inside a synchronized (this) block.
15293     */
15294    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15295        if(isDiff) {
15296            SystemProperties.set("user.language", l.getLanguage());
15297            SystemProperties.set("user.region", l.getCountry());
15298        }
15299
15300        if(isPersist) {
15301            SystemProperties.set("persist.sys.language", l.getLanguage());
15302            SystemProperties.set("persist.sys.country", l.getCountry());
15303            SystemProperties.set("persist.sys.localevar", l.getVariant());
15304        }
15305    }
15306
15307    @Override
15308    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15309        ActivityRecord srec = ActivityRecord.forToken(token);
15310        return srec != null && srec.task.affinity != null &&
15311                srec.task.affinity.equals(destAffinity);
15312    }
15313
15314    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15315            Intent resultData) {
15316
15317        synchronized (this) {
15318            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15319            if (stack != null) {
15320                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15321            }
15322            return false;
15323        }
15324    }
15325
15326    public int getLaunchedFromUid(IBinder activityToken) {
15327        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15328        if (srec == null) {
15329            return -1;
15330        }
15331        return srec.launchedFromUid;
15332    }
15333
15334    public String getLaunchedFromPackage(IBinder activityToken) {
15335        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15336        if (srec == null) {
15337            return null;
15338        }
15339        return srec.launchedFromPackage;
15340    }
15341
15342    // =========================================================
15343    // LIFETIME MANAGEMENT
15344    // =========================================================
15345
15346    // Returns which broadcast queue the app is the current [or imminent] receiver
15347    // on, or 'null' if the app is not an active broadcast recipient.
15348    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15349        BroadcastRecord r = app.curReceiver;
15350        if (r != null) {
15351            return r.queue;
15352        }
15353
15354        // It's not the current receiver, but it might be starting up to become one
15355        synchronized (this) {
15356            for (BroadcastQueue queue : mBroadcastQueues) {
15357                r = queue.mPendingBroadcast;
15358                if (r != null && r.curApp == app) {
15359                    // found it; report which queue it's in
15360                    return queue;
15361                }
15362            }
15363        }
15364
15365        return null;
15366    }
15367
15368    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15369            boolean doingAll, long now) {
15370        if (mAdjSeq == app.adjSeq) {
15371            // This adjustment has already been computed.
15372            return app.curRawAdj;
15373        }
15374
15375        if (app.thread == null) {
15376            app.adjSeq = mAdjSeq;
15377            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15378            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15379            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15380        }
15381
15382        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15383        app.adjSource = null;
15384        app.adjTarget = null;
15385        app.empty = false;
15386        app.cached = false;
15387
15388        final int activitiesSize = app.activities.size();
15389
15390        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15391            // The max adjustment doesn't allow this app to be anything
15392            // below foreground, so it is not worth doing work for it.
15393            app.adjType = "fixed";
15394            app.adjSeq = mAdjSeq;
15395            app.curRawAdj = app.maxAdj;
15396            app.foregroundActivities = false;
15397            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15398            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15399            // System processes can do UI, and when they do we want to have
15400            // them trim their memory after the user leaves the UI.  To
15401            // facilitate this, here we need to determine whether or not it
15402            // is currently showing UI.
15403            app.systemNoUi = true;
15404            if (app == TOP_APP) {
15405                app.systemNoUi = false;
15406            } else if (activitiesSize > 0) {
15407                for (int j = 0; j < activitiesSize; j++) {
15408                    final ActivityRecord r = app.activities.get(j);
15409                    if (r.visible) {
15410                        app.systemNoUi = false;
15411                    }
15412                }
15413            }
15414            if (!app.systemNoUi) {
15415                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15416            }
15417            return (app.curAdj=app.maxAdj);
15418        }
15419
15420        app.systemNoUi = false;
15421
15422        // Determine the importance of the process, starting with most
15423        // important to least, and assign an appropriate OOM adjustment.
15424        int adj;
15425        int schedGroup;
15426        int procState;
15427        boolean foregroundActivities = false;
15428        BroadcastQueue queue;
15429        if (app == TOP_APP) {
15430            // The last app on the list is the foreground app.
15431            adj = ProcessList.FOREGROUND_APP_ADJ;
15432            schedGroup = Process.THREAD_GROUP_DEFAULT;
15433            app.adjType = "top-activity";
15434            foregroundActivities = true;
15435            procState = ActivityManager.PROCESS_STATE_TOP;
15436        } else if (app.instrumentationClass != null) {
15437            // Don't want to kill running instrumentation.
15438            adj = ProcessList.FOREGROUND_APP_ADJ;
15439            schedGroup = Process.THREAD_GROUP_DEFAULT;
15440            app.adjType = "instrumentation";
15441            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15442        } else if ((queue = isReceivingBroadcast(app)) != null) {
15443            // An app that is currently receiving a broadcast also
15444            // counts as being in the foreground for OOM killer purposes.
15445            // It's placed in a sched group based on the nature of the
15446            // broadcast as reflected by which queue it's active in.
15447            adj = ProcessList.FOREGROUND_APP_ADJ;
15448            schedGroup = (queue == mFgBroadcastQueue)
15449                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15450            app.adjType = "broadcast";
15451            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15452        } else if (app.executingServices.size() > 0) {
15453            // An app that is currently executing a service callback also
15454            // counts as being in the foreground.
15455            adj = ProcessList.FOREGROUND_APP_ADJ;
15456            schedGroup = app.execServicesFg ?
15457                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15458            app.adjType = "exec-service";
15459            procState = ActivityManager.PROCESS_STATE_SERVICE;
15460            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15461        } else {
15462            // As far as we know the process is empty.  We may change our mind later.
15463            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15464            // At this point we don't actually know the adjustment.  Use the cached adj
15465            // value that the caller wants us to.
15466            adj = cachedAdj;
15467            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15468            app.cached = true;
15469            app.empty = true;
15470            app.adjType = "cch-empty";
15471        }
15472
15473        // Examine all activities if not already foreground.
15474        if (!foregroundActivities && activitiesSize > 0) {
15475            for (int j = 0; j < activitiesSize; j++) {
15476                final ActivityRecord r = app.activities.get(j);
15477                if (r.app != app) {
15478                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15479                            + app + "?!?");
15480                    continue;
15481                }
15482                if (r.visible) {
15483                    // App has a visible activity; only upgrade adjustment.
15484                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15485                        adj = ProcessList.VISIBLE_APP_ADJ;
15486                        app.adjType = "visible";
15487                    }
15488                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15489                        procState = ActivityManager.PROCESS_STATE_TOP;
15490                    }
15491                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15492                    app.cached = false;
15493                    app.empty = false;
15494                    foregroundActivities = true;
15495                    break;
15496                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15497                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15498                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15499                        app.adjType = "pausing";
15500                    }
15501                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15502                        procState = ActivityManager.PROCESS_STATE_TOP;
15503                    }
15504                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15505                    app.cached = false;
15506                    app.empty = false;
15507                    foregroundActivities = true;
15508                } else if (r.state == ActivityState.STOPPING) {
15509                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15510                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15511                        app.adjType = "stopping";
15512                    }
15513                    // For the process state, we will at this point consider the
15514                    // process to be cached.  It will be cached either as an activity
15515                    // or empty depending on whether the activity is finishing.  We do
15516                    // this so that we can treat the process as cached for purposes of
15517                    // memory trimming (determing current memory level, trim command to
15518                    // send to process) since there can be an arbitrary number of stopping
15519                    // processes and they should soon all go into the cached state.
15520                    if (!r.finishing) {
15521                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15522                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15523                        }
15524                    }
15525                    app.cached = false;
15526                    app.empty = false;
15527                    foregroundActivities = true;
15528                } else {
15529                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15530                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15531                        app.adjType = "cch-act";
15532                    }
15533                }
15534            }
15535        }
15536
15537        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15538            if (app.foregroundServices) {
15539                // The user is aware of this app, so make it visible.
15540                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15541                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15542                app.cached = false;
15543                app.adjType = "fg-service";
15544                schedGroup = Process.THREAD_GROUP_DEFAULT;
15545            } else if (app.forcingToForeground != null) {
15546                // The user is aware of this app, so make it visible.
15547                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15548                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15549                app.cached = false;
15550                app.adjType = "force-fg";
15551                app.adjSource = app.forcingToForeground;
15552                schedGroup = Process.THREAD_GROUP_DEFAULT;
15553            }
15554        }
15555
15556        if (app == mHeavyWeightProcess) {
15557            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15558                // We don't want to kill the current heavy-weight process.
15559                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15560                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15561                app.cached = false;
15562                app.adjType = "heavy";
15563            }
15564            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15565                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15566            }
15567        }
15568
15569        if (app == mHomeProcess) {
15570            if (adj > ProcessList.HOME_APP_ADJ) {
15571                // This process is hosting what we currently consider to be the
15572                // home app, so we don't want to let it go into the background.
15573                adj = ProcessList.HOME_APP_ADJ;
15574                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15575                app.cached = false;
15576                app.adjType = "home";
15577            }
15578            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15579                procState = ActivityManager.PROCESS_STATE_HOME;
15580            }
15581        }
15582
15583        if (app == mPreviousProcess && app.activities.size() > 0) {
15584            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15585                // This was the previous process that showed UI to the user.
15586                // We want to try to keep it around more aggressively, to give
15587                // a good experience around switching between two apps.
15588                adj = ProcessList.PREVIOUS_APP_ADJ;
15589                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15590                app.cached = false;
15591                app.adjType = "previous";
15592            }
15593            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15594                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15595            }
15596        }
15597
15598        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15599                + " reason=" + app.adjType);
15600
15601        // By default, we use the computed adjustment.  It may be changed if
15602        // there are applications dependent on our services or providers, but
15603        // this gives us a baseline and makes sure we don't get into an
15604        // infinite recursion.
15605        app.adjSeq = mAdjSeq;
15606        app.curRawAdj = adj;
15607        app.hasStartedServices = false;
15608
15609        if (mBackupTarget != null && app == mBackupTarget.app) {
15610            // If possible we want to avoid killing apps while they're being backed up
15611            if (adj > ProcessList.BACKUP_APP_ADJ) {
15612                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15613                adj = ProcessList.BACKUP_APP_ADJ;
15614                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15615                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15616                }
15617                app.adjType = "backup";
15618                app.cached = false;
15619            }
15620            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15621                procState = ActivityManager.PROCESS_STATE_BACKUP;
15622            }
15623        }
15624
15625        boolean mayBeTop = false;
15626
15627        for (int is = app.services.size()-1;
15628                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15629                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15630                        || procState > ActivityManager.PROCESS_STATE_TOP);
15631                is--) {
15632            ServiceRecord s = app.services.valueAt(is);
15633            if (s.startRequested) {
15634                app.hasStartedServices = true;
15635                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15636                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15637                }
15638                if (app.hasShownUi && app != mHomeProcess) {
15639                    // If this process has shown some UI, let it immediately
15640                    // go to the LRU list because it may be pretty heavy with
15641                    // UI stuff.  We'll tag it with a label just to help
15642                    // debug and understand what is going on.
15643                    if (adj > ProcessList.SERVICE_ADJ) {
15644                        app.adjType = "cch-started-ui-services";
15645                    }
15646                } else {
15647                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15648                        // This service has seen some activity within
15649                        // recent memory, so we will keep its process ahead
15650                        // of the background processes.
15651                        if (adj > ProcessList.SERVICE_ADJ) {
15652                            adj = ProcessList.SERVICE_ADJ;
15653                            app.adjType = "started-services";
15654                            app.cached = false;
15655                        }
15656                    }
15657                    // If we have let the service slide into the background
15658                    // state, still have some text describing what it is doing
15659                    // even though the service no longer has an impact.
15660                    if (adj > ProcessList.SERVICE_ADJ) {
15661                        app.adjType = "cch-started-services";
15662                    }
15663                }
15664            }
15665            for (int conni = s.connections.size()-1;
15666                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15667                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15668                            || procState > ActivityManager.PROCESS_STATE_TOP);
15669                    conni--) {
15670                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15671                for (int i = 0;
15672                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15673                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15674                                || procState > ActivityManager.PROCESS_STATE_TOP);
15675                        i++) {
15676                    // XXX should compute this based on the max of
15677                    // all connected clients.
15678                    ConnectionRecord cr = clist.get(i);
15679                    if (cr.binding.client == app) {
15680                        // Binding to ourself is not interesting.
15681                        continue;
15682                    }
15683                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15684                        ProcessRecord client = cr.binding.client;
15685                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15686                                TOP_APP, doingAll, now);
15687                        int clientProcState = client.curProcState;
15688                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15689                            // If the other app is cached for any reason, for purposes here
15690                            // we are going to consider it empty.  The specific cached state
15691                            // doesn't propagate except under certain conditions.
15692                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15693                        }
15694                        String adjType = null;
15695                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15696                            // Not doing bind OOM management, so treat
15697                            // this guy more like a started service.
15698                            if (app.hasShownUi && app != mHomeProcess) {
15699                                // If this process has shown some UI, let it immediately
15700                                // go to the LRU list because it may be pretty heavy with
15701                                // UI stuff.  We'll tag it with a label just to help
15702                                // debug and understand what is going on.
15703                                if (adj > clientAdj) {
15704                                    adjType = "cch-bound-ui-services";
15705                                }
15706                                app.cached = false;
15707                                clientAdj = adj;
15708                                clientProcState = procState;
15709                            } else {
15710                                if (now >= (s.lastActivity
15711                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15712                                    // This service has not seen activity within
15713                                    // recent memory, so allow it to drop to the
15714                                    // LRU list if there is no other reason to keep
15715                                    // it around.  We'll also tag it with a label just
15716                                    // to help debug and undertand what is going on.
15717                                    if (adj > clientAdj) {
15718                                        adjType = "cch-bound-services";
15719                                    }
15720                                    clientAdj = adj;
15721                                }
15722                            }
15723                        }
15724                        if (adj > clientAdj) {
15725                            // If this process has recently shown UI, and
15726                            // the process that is binding to it is less
15727                            // important than being visible, then we don't
15728                            // care about the binding as much as we care
15729                            // about letting this process get into the LRU
15730                            // list to be killed and restarted if needed for
15731                            // memory.
15732                            if (app.hasShownUi && app != mHomeProcess
15733                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15734                                adjType = "cch-bound-ui-services";
15735                            } else {
15736                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15737                                        |Context.BIND_IMPORTANT)) != 0) {
15738                                    adj = clientAdj;
15739                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15740                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15741                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15742                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15743                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15744                                    adj = clientAdj;
15745                                } else {
15746                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15747                                        adj = ProcessList.VISIBLE_APP_ADJ;
15748                                    }
15749                                }
15750                                if (!client.cached) {
15751                                    app.cached = false;
15752                                }
15753                                adjType = "service";
15754                            }
15755                        }
15756                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15757                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15758                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15759                            }
15760                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15761                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15762                                    // Special handling of clients who are in the top state.
15763                                    // We *may* want to consider this process to be in the
15764                                    // top state as well, but only if there is not another
15765                                    // reason for it to be running.  Being on the top is a
15766                                    // special state, meaning you are specifically running
15767                                    // for the current top app.  If the process is already
15768                                    // running in the background for some other reason, it
15769                                    // is more important to continue considering it to be
15770                                    // in the background state.
15771                                    mayBeTop = true;
15772                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15773                                } else {
15774                                    // Special handling for above-top states (persistent
15775                                    // processes).  These should not bring the current process
15776                                    // into the top state, since they are not on top.  Instead
15777                                    // give them the best state after that.
15778                                    clientProcState =
15779                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15780                                }
15781                            }
15782                        } else {
15783                            if (clientProcState <
15784                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15785                                clientProcState =
15786                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15787                            }
15788                        }
15789                        if (procState > clientProcState) {
15790                            procState = clientProcState;
15791                        }
15792                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15793                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15794                            app.pendingUiClean = true;
15795                        }
15796                        if (adjType != null) {
15797                            app.adjType = adjType;
15798                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15799                                    .REASON_SERVICE_IN_USE;
15800                            app.adjSource = cr.binding.client;
15801                            app.adjSourceProcState = clientProcState;
15802                            app.adjTarget = s.name;
15803                        }
15804                    }
15805                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15806                        app.treatLikeActivity = true;
15807                    }
15808                    final ActivityRecord a = cr.activity;
15809                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15810                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15811                                (a.visible || a.state == ActivityState.RESUMED
15812                                 || a.state == ActivityState.PAUSING)) {
15813                            adj = ProcessList.FOREGROUND_APP_ADJ;
15814                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15815                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15816                            }
15817                            app.cached = false;
15818                            app.adjType = "service";
15819                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15820                                    .REASON_SERVICE_IN_USE;
15821                            app.adjSource = a;
15822                            app.adjSourceProcState = procState;
15823                            app.adjTarget = s.name;
15824                        }
15825                    }
15826                }
15827            }
15828        }
15829
15830        for (int provi = app.pubProviders.size()-1;
15831                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15832                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15833                        || procState > ActivityManager.PROCESS_STATE_TOP);
15834                provi--) {
15835            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15836            for (int i = cpr.connections.size()-1;
15837                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15838                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15839                            || procState > ActivityManager.PROCESS_STATE_TOP);
15840                    i--) {
15841                ContentProviderConnection conn = cpr.connections.get(i);
15842                ProcessRecord client = conn.client;
15843                if (client == app) {
15844                    // Being our own client is not interesting.
15845                    continue;
15846                }
15847                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15848                int clientProcState = client.curProcState;
15849                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15850                    // If the other app is cached for any reason, for purposes here
15851                    // we are going to consider it empty.
15852                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15853                }
15854                if (adj > clientAdj) {
15855                    if (app.hasShownUi && app != mHomeProcess
15856                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15857                        app.adjType = "cch-ui-provider";
15858                    } else {
15859                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15860                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15861                        app.adjType = "provider";
15862                    }
15863                    app.cached &= client.cached;
15864                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15865                            .REASON_PROVIDER_IN_USE;
15866                    app.adjSource = client;
15867                    app.adjSourceProcState = clientProcState;
15868                    app.adjTarget = cpr.name;
15869                }
15870                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15871                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15872                        // Special handling of clients who are in the top state.
15873                        // We *may* want to consider this process to be in the
15874                        // top state as well, but only if there is not another
15875                        // reason for it to be running.  Being on the top is a
15876                        // special state, meaning you are specifically running
15877                        // for the current top app.  If the process is already
15878                        // running in the background for some other reason, it
15879                        // is more important to continue considering it to be
15880                        // in the background state.
15881                        mayBeTop = true;
15882                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15883                    } else {
15884                        // Special handling for above-top states (persistent
15885                        // processes).  These should not bring the current process
15886                        // into the top state, since they are not on top.  Instead
15887                        // give them the best state after that.
15888                        clientProcState =
15889                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15890                    }
15891                }
15892                if (procState > clientProcState) {
15893                    procState = clientProcState;
15894                }
15895                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15896                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15897                }
15898            }
15899            // If the provider has external (non-framework) process
15900            // dependencies, ensure that its adjustment is at least
15901            // FOREGROUND_APP_ADJ.
15902            if (cpr.hasExternalProcessHandles()) {
15903                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15904                    adj = ProcessList.FOREGROUND_APP_ADJ;
15905                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15906                    app.cached = false;
15907                    app.adjType = "provider";
15908                    app.adjTarget = cpr.name;
15909                }
15910                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15911                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15912                }
15913            }
15914        }
15915
15916        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15917            // A client of one of our services or providers is in the top state.  We
15918            // *may* want to be in the top state, but not if we are already running in
15919            // the background for some other reason.  For the decision here, we are going
15920            // to pick out a few specific states that we want to remain in when a client
15921            // is top (states that tend to be longer-term) and otherwise allow it to go
15922            // to the top state.
15923            switch (procState) {
15924                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15925                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15926                case ActivityManager.PROCESS_STATE_SERVICE:
15927                    // These all are longer-term states, so pull them up to the top
15928                    // of the background states, but not all the way to the top state.
15929                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15930                    break;
15931                default:
15932                    // Otherwise, top is a better choice, so take it.
15933                    procState = ActivityManager.PROCESS_STATE_TOP;
15934                    break;
15935            }
15936        }
15937
15938        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15939            if (app.hasClientActivities) {
15940                // This is a cached process, but with client activities.  Mark it so.
15941                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15942                app.adjType = "cch-client-act";
15943            } else if (app.treatLikeActivity) {
15944                // This is a cached process, but somebody wants us to treat it like it has
15945                // an activity, okay!
15946                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15947                app.adjType = "cch-as-act";
15948            }
15949        }
15950
15951        if (adj == ProcessList.SERVICE_ADJ) {
15952            if (doingAll) {
15953                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15954                mNewNumServiceProcs++;
15955                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15956                if (!app.serviceb) {
15957                    // This service isn't far enough down on the LRU list to
15958                    // normally be a B service, but if we are low on RAM and it
15959                    // is large we want to force it down since we would prefer to
15960                    // keep launcher over it.
15961                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15962                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15963                        app.serviceHighRam = true;
15964                        app.serviceb = true;
15965                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15966                    } else {
15967                        mNewNumAServiceProcs++;
15968                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15969                    }
15970                } else {
15971                    app.serviceHighRam = false;
15972                }
15973            }
15974            if (app.serviceb) {
15975                adj = ProcessList.SERVICE_B_ADJ;
15976            }
15977        }
15978
15979        app.curRawAdj = adj;
15980
15981        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15982        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15983        if (adj > app.maxAdj) {
15984            adj = app.maxAdj;
15985            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15986                schedGroup = Process.THREAD_GROUP_DEFAULT;
15987            }
15988        }
15989
15990        // Do final modification to adj.  Everything we do between here and applying
15991        // the final setAdj must be done in this function, because we will also use
15992        // it when computing the final cached adj later.  Note that we don't need to
15993        // worry about this for max adj above, since max adj will always be used to
15994        // keep it out of the cached vaues.
15995        app.curAdj = app.modifyRawOomAdj(adj);
15996        app.curSchedGroup = schedGroup;
15997        app.curProcState = procState;
15998        app.foregroundActivities = foregroundActivities;
15999
16000        return app.curRawAdj;
16001    }
16002
16003    /**
16004     * Schedule PSS collection of a process.
16005     */
16006    void requestPssLocked(ProcessRecord proc, int procState) {
16007        if (mPendingPssProcesses.contains(proc)) {
16008            return;
16009        }
16010        if (mPendingPssProcesses.size() == 0) {
16011            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16012        }
16013        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16014        proc.pssProcState = procState;
16015        mPendingPssProcesses.add(proc);
16016    }
16017
16018    /**
16019     * Schedule PSS collection of all processes.
16020     */
16021    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16022        if (!always) {
16023            if (now < (mLastFullPssTime +
16024                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16025                return;
16026            }
16027        }
16028        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16029        mLastFullPssTime = now;
16030        mFullPssPending = true;
16031        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16032        mPendingPssProcesses.clear();
16033        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16034            ProcessRecord app = mLruProcesses.get(i);
16035            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16036                app.pssProcState = app.setProcState;
16037                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16038                        isSleeping(), now);
16039                mPendingPssProcesses.add(app);
16040            }
16041        }
16042        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16043    }
16044
16045    /**
16046     * Ask a given process to GC right now.
16047     */
16048    final void performAppGcLocked(ProcessRecord app) {
16049        try {
16050            app.lastRequestedGc = SystemClock.uptimeMillis();
16051            if (app.thread != null) {
16052                if (app.reportLowMemory) {
16053                    app.reportLowMemory = false;
16054                    app.thread.scheduleLowMemory();
16055                } else {
16056                    app.thread.processInBackground();
16057                }
16058            }
16059        } catch (Exception e) {
16060            // whatever.
16061        }
16062    }
16063
16064    /**
16065     * Returns true if things are idle enough to perform GCs.
16066     */
16067    private final boolean canGcNowLocked() {
16068        boolean processingBroadcasts = false;
16069        for (BroadcastQueue q : mBroadcastQueues) {
16070            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16071                processingBroadcasts = true;
16072            }
16073        }
16074        return !processingBroadcasts
16075                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16076    }
16077
16078    /**
16079     * Perform GCs on all processes that are waiting for it, but only
16080     * if things are idle.
16081     */
16082    final void performAppGcsLocked() {
16083        final int N = mProcessesToGc.size();
16084        if (N <= 0) {
16085            return;
16086        }
16087        if (canGcNowLocked()) {
16088            while (mProcessesToGc.size() > 0) {
16089                ProcessRecord proc = mProcessesToGc.remove(0);
16090                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16091                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16092                            <= SystemClock.uptimeMillis()) {
16093                        // To avoid spamming the system, we will GC processes one
16094                        // at a time, waiting a few seconds between each.
16095                        performAppGcLocked(proc);
16096                        scheduleAppGcsLocked();
16097                        return;
16098                    } else {
16099                        // It hasn't been long enough since we last GCed this
16100                        // process...  put it in the list to wait for its time.
16101                        addProcessToGcListLocked(proc);
16102                        break;
16103                    }
16104                }
16105            }
16106
16107            scheduleAppGcsLocked();
16108        }
16109    }
16110
16111    /**
16112     * If all looks good, perform GCs on all processes waiting for them.
16113     */
16114    final void performAppGcsIfAppropriateLocked() {
16115        if (canGcNowLocked()) {
16116            performAppGcsLocked();
16117            return;
16118        }
16119        // Still not idle, wait some more.
16120        scheduleAppGcsLocked();
16121    }
16122
16123    /**
16124     * Schedule the execution of all pending app GCs.
16125     */
16126    final void scheduleAppGcsLocked() {
16127        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16128
16129        if (mProcessesToGc.size() > 0) {
16130            // Schedule a GC for the time to the next process.
16131            ProcessRecord proc = mProcessesToGc.get(0);
16132            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16133
16134            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16135            long now = SystemClock.uptimeMillis();
16136            if (when < (now+GC_TIMEOUT)) {
16137                when = now + GC_TIMEOUT;
16138            }
16139            mHandler.sendMessageAtTime(msg, when);
16140        }
16141    }
16142
16143    /**
16144     * Add a process to the array of processes waiting to be GCed.  Keeps the
16145     * list in sorted order by the last GC time.  The process can't already be
16146     * on the list.
16147     */
16148    final void addProcessToGcListLocked(ProcessRecord proc) {
16149        boolean added = false;
16150        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16151            if (mProcessesToGc.get(i).lastRequestedGc <
16152                    proc.lastRequestedGc) {
16153                added = true;
16154                mProcessesToGc.add(i+1, proc);
16155                break;
16156            }
16157        }
16158        if (!added) {
16159            mProcessesToGc.add(0, proc);
16160        }
16161    }
16162
16163    /**
16164     * Set up to ask a process to GC itself.  This will either do it
16165     * immediately, or put it on the list of processes to gc the next
16166     * time things are idle.
16167     */
16168    final void scheduleAppGcLocked(ProcessRecord app) {
16169        long now = SystemClock.uptimeMillis();
16170        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16171            return;
16172        }
16173        if (!mProcessesToGc.contains(app)) {
16174            addProcessToGcListLocked(app);
16175            scheduleAppGcsLocked();
16176        }
16177    }
16178
16179    final void checkExcessivePowerUsageLocked(boolean doKills) {
16180        updateCpuStatsNow();
16181
16182        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16183        boolean doWakeKills = doKills;
16184        boolean doCpuKills = doKills;
16185        if (mLastPowerCheckRealtime == 0) {
16186            doWakeKills = false;
16187        }
16188        if (mLastPowerCheckUptime == 0) {
16189            doCpuKills = false;
16190        }
16191        if (stats.isScreenOn()) {
16192            doWakeKills = false;
16193        }
16194        final long curRealtime = SystemClock.elapsedRealtime();
16195        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16196        final long curUptime = SystemClock.uptimeMillis();
16197        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16198        mLastPowerCheckRealtime = curRealtime;
16199        mLastPowerCheckUptime = curUptime;
16200        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16201            doWakeKills = false;
16202        }
16203        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16204            doCpuKills = false;
16205        }
16206        int i = mLruProcesses.size();
16207        while (i > 0) {
16208            i--;
16209            ProcessRecord app = mLruProcesses.get(i);
16210            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16211                long wtime;
16212                synchronized (stats) {
16213                    wtime = stats.getProcessWakeTime(app.info.uid,
16214                            app.pid, curRealtime);
16215                }
16216                long wtimeUsed = wtime - app.lastWakeTime;
16217                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16218                if (DEBUG_POWER) {
16219                    StringBuilder sb = new StringBuilder(128);
16220                    sb.append("Wake for ");
16221                    app.toShortString(sb);
16222                    sb.append(": over ");
16223                    TimeUtils.formatDuration(realtimeSince, sb);
16224                    sb.append(" used ");
16225                    TimeUtils.formatDuration(wtimeUsed, sb);
16226                    sb.append(" (");
16227                    sb.append((wtimeUsed*100)/realtimeSince);
16228                    sb.append("%)");
16229                    Slog.i(TAG, sb.toString());
16230                    sb.setLength(0);
16231                    sb.append("CPU for ");
16232                    app.toShortString(sb);
16233                    sb.append(": over ");
16234                    TimeUtils.formatDuration(uptimeSince, sb);
16235                    sb.append(" used ");
16236                    TimeUtils.formatDuration(cputimeUsed, sb);
16237                    sb.append(" (");
16238                    sb.append((cputimeUsed*100)/uptimeSince);
16239                    sb.append("%)");
16240                    Slog.i(TAG, sb.toString());
16241                }
16242                // If a process has held a wake lock for more
16243                // than 50% of the time during this period,
16244                // that sounds bad.  Kill!
16245                if (doWakeKills && realtimeSince > 0
16246                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16247                    synchronized (stats) {
16248                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16249                                realtimeSince, wtimeUsed);
16250                    }
16251                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16252                            + " during " + realtimeSince);
16253                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16254                } else if (doCpuKills && uptimeSince > 0
16255                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16256                    synchronized (stats) {
16257                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16258                                uptimeSince, cputimeUsed);
16259                    }
16260                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16261                            + " during " + uptimeSince);
16262                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16263                } else {
16264                    app.lastWakeTime = wtime;
16265                    app.lastCpuTime = app.curCpuTime;
16266                }
16267            }
16268        }
16269    }
16270
16271    private final boolean applyOomAdjLocked(ProcessRecord app,
16272            ProcessRecord TOP_APP, boolean doingAll, long now) {
16273        boolean success = true;
16274
16275        if (app.curRawAdj != app.setRawAdj) {
16276            app.setRawAdj = app.curRawAdj;
16277        }
16278
16279        int changes = 0;
16280
16281        if (app.curAdj != app.setAdj) {
16282            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16283            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16284                TAG, "Set " + app.pid + " " + app.processName +
16285                " adj " + app.curAdj + ": " + app.adjType);
16286            app.setAdj = app.curAdj;
16287        }
16288
16289        if (app.setSchedGroup != app.curSchedGroup) {
16290            app.setSchedGroup = app.curSchedGroup;
16291            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16292                    "Setting process group of " + app.processName
16293                    + " to " + app.curSchedGroup);
16294            if (app.waitingToKill != null &&
16295                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16296                killUnneededProcessLocked(app, app.waitingToKill);
16297                success = false;
16298            } else {
16299                if (true) {
16300                    long oldId = Binder.clearCallingIdentity();
16301                    try {
16302                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16303                    } catch (Exception e) {
16304                        Slog.w(TAG, "Failed setting process group of " + app.pid
16305                                + " to " + app.curSchedGroup);
16306                        e.printStackTrace();
16307                    } finally {
16308                        Binder.restoreCallingIdentity(oldId);
16309                    }
16310                } else {
16311                    if (app.thread != null) {
16312                        try {
16313                            app.thread.setSchedulingGroup(app.curSchedGroup);
16314                        } catch (RemoteException e) {
16315                        }
16316                    }
16317                }
16318                Process.setSwappiness(app.pid,
16319                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16320            }
16321        }
16322        if (app.repForegroundActivities != app.foregroundActivities) {
16323            app.repForegroundActivities = app.foregroundActivities;
16324            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16325        }
16326        if (app.repProcState != app.curProcState) {
16327            app.repProcState = app.curProcState;
16328            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16329            if (app.thread != null) {
16330                try {
16331                    if (false) {
16332                        //RuntimeException h = new RuntimeException("here");
16333                        Slog.i(TAG, "Sending new process state " + app.repProcState
16334                                + " to " + app /*, h*/);
16335                    }
16336                    app.thread.setProcessState(app.repProcState);
16337                } catch (RemoteException e) {
16338                }
16339            }
16340        }
16341        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16342                app.setProcState)) {
16343            app.lastStateTime = now;
16344            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16345                    isSleeping(), now);
16346            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16347                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16348                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16349                    + (app.nextPssTime-now) + ": " + app);
16350        } else {
16351            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16352                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16353                requestPssLocked(app, app.setProcState);
16354                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16355                        isSleeping(), now);
16356            } else if (false && DEBUG_PSS) {
16357                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16358            }
16359        }
16360        if (app.setProcState != app.curProcState) {
16361            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16362                    "Proc state change of " + app.processName
16363                    + " to " + app.curProcState);
16364            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16365            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16366            if (setImportant && !curImportant) {
16367                // This app is no longer something we consider important enough to allow to
16368                // use arbitrary amounts of battery power.  Note
16369                // its current wake lock time to later know to kill it if
16370                // it is not behaving well.
16371                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16372                synchronized (stats) {
16373                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16374                            app.pid, SystemClock.elapsedRealtime());
16375                }
16376                app.lastCpuTime = app.curCpuTime;
16377
16378            }
16379            app.setProcState = app.curProcState;
16380            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16381                app.notCachedSinceIdle = false;
16382            }
16383            if (!doingAll) {
16384                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16385            } else {
16386                app.procStateChanged = true;
16387            }
16388        }
16389
16390        if (changes != 0) {
16391            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16392            int i = mPendingProcessChanges.size()-1;
16393            ProcessChangeItem item = null;
16394            while (i >= 0) {
16395                item = mPendingProcessChanges.get(i);
16396                if (item.pid == app.pid) {
16397                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16398                    break;
16399                }
16400                i--;
16401            }
16402            if (i < 0) {
16403                // No existing item in pending changes; need a new one.
16404                final int NA = mAvailProcessChanges.size();
16405                if (NA > 0) {
16406                    item = mAvailProcessChanges.remove(NA-1);
16407                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16408                } else {
16409                    item = new ProcessChangeItem();
16410                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16411                }
16412                item.changes = 0;
16413                item.pid = app.pid;
16414                item.uid = app.info.uid;
16415                if (mPendingProcessChanges.size() == 0) {
16416                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16417                            "*** Enqueueing dispatch processes changed!");
16418                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16419                }
16420                mPendingProcessChanges.add(item);
16421            }
16422            item.changes |= changes;
16423            item.processState = app.repProcState;
16424            item.foregroundActivities = app.repForegroundActivities;
16425            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16426                    + Integer.toHexString(System.identityHashCode(item))
16427                    + " " + app.toShortString() + ": changes=" + item.changes
16428                    + " procState=" + item.processState
16429                    + " foreground=" + item.foregroundActivities
16430                    + " type=" + app.adjType + " source=" + app.adjSource
16431                    + " target=" + app.adjTarget);
16432        }
16433
16434        return success;
16435    }
16436
16437    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16438        if (proc.thread != null) {
16439            if (proc.baseProcessTracker != null) {
16440                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16441            }
16442            if (proc.repProcState >= 0) {
16443                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16444                        proc.repProcState);
16445            }
16446        }
16447    }
16448
16449    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16450            ProcessRecord TOP_APP, boolean doingAll, long now) {
16451        if (app.thread == null) {
16452            return false;
16453        }
16454
16455        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16456
16457        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16458    }
16459
16460    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16461            boolean oomAdj) {
16462        if (isForeground != proc.foregroundServices) {
16463            proc.foregroundServices = isForeground;
16464            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16465                    proc.info.uid);
16466            if (isForeground) {
16467                if (curProcs == null) {
16468                    curProcs = new ArrayList<ProcessRecord>();
16469                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16470                }
16471                if (!curProcs.contains(proc)) {
16472                    curProcs.add(proc);
16473                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16474                            proc.info.packageName, proc.info.uid);
16475                }
16476            } else {
16477                if (curProcs != null) {
16478                    if (curProcs.remove(proc)) {
16479                        mBatteryStatsService.noteEvent(
16480                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16481                                proc.info.packageName, proc.info.uid);
16482                        if (curProcs.size() <= 0) {
16483                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16484                        }
16485                    }
16486                }
16487            }
16488            if (oomAdj) {
16489                updateOomAdjLocked();
16490            }
16491        }
16492    }
16493
16494    private final ActivityRecord resumedAppLocked() {
16495        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16496        String pkg;
16497        int uid;
16498        if (act != null) {
16499            pkg = act.packageName;
16500            uid = act.info.applicationInfo.uid;
16501        } else {
16502            pkg = null;
16503            uid = -1;
16504        }
16505        // Has the UID or resumed package name changed?
16506        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16507                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16508            if (mCurResumedPackage != null) {
16509                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16510                        mCurResumedPackage, mCurResumedUid);
16511            }
16512            mCurResumedPackage = pkg;
16513            mCurResumedUid = uid;
16514            if (mCurResumedPackage != null) {
16515                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16516                        mCurResumedPackage, mCurResumedUid);
16517            }
16518        }
16519        return act;
16520    }
16521
16522    final boolean updateOomAdjLocked(ProcessRecord app) {
16523        final ActivityRecord TOP_ACT = resumedAppLocked();
16524        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16525        final boolean wasCached = app.cached;
16526
16527        mAdjSeq++;
16528
16529        // This is the desired cached adjusment we want to tell it to use.
16530        // If our app is currently cached, we know it, and that is it.  Otherwise,
16531        // we don't know it yet, and it needs to now be cached we will then
16532        // need to do a complete oom adj.
16533        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16534                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16535        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16536                SystemClock.uptimeMillis());
16537        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16538            // Changed to/from cached state, so apps after it in the LRU
16539            // list may also be changed.
16540            updateOomAdjLocked();
16541        }
16542        return success;
16543    }
16544
16545    final void updateOomAdjLocked() {
16546        final ActivityRecord TOP_ACT = resumedAppLocked();
16547        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16548        final long now = SystemClock.uptimeMillis();
16549        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16550        final int N = mLruProcesses.size();
16551
16552        if (false) {
16553            RuntimeException e = new RuntimeException();
16554            e.fillInStackTrace();
16555            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16556        }
16557
16558        mAdjSeq++;
16559        mNewNumServiceProcs = 0;
16560        mNewNumAServiceProcs = 0;
16561
16562        final int emptyProcessLimit;
16563        final int cachedProcessLimit;
16564        if (mProcessLimit <= 0) {
16565            emptyProcessLimit = cachedProcessLimit = 0;
16566        } else if (mProcessLimit == 1) {
16567            emptyProcessLimit = 1;
16568            cachedProcessLimit = 0;
16569        } else {
16570            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16571            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16572        }
16573
16574        // Let's determine how many processes we have running vs.
16575        // how many slots we have for background processes; we may want
16576        // to put multiple processes in a slot of there are enough of
16577        // them.
16578        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16579                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16580        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16581        if (numEmptyProcs > cachedProcessLimit) {
16582            // If there are more empty processes than our limit on cached
16583            // processes, then use the cached process limit for the factor.
16584            // This ensures that the really old empty processes get pushed
16585            // down to the bottom, so if we are running low on memory we will
16586            // have a better chance at keeping around more cached processes
16587            // instead of a gazillion empty processes.
16588            numEmptyProcs = cachedProcessLimit;
16589        }
16590        int emptyFactor = numEmptyProcs/numSlots;
16591        if (emptyFactor < 1) emptyFactor = 1;
16592        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16593        if (cachedFactor < 1) cachedFactor = 1;
16594        int stepCached = 0;
16595        int stepEmpty = 0;
16596        int numCached = 0;
16597        int numEmpty = 0;
16598        int numTrimming = 0;
16599
16600        mNumNonCachedProcs = 0;
16601        mNumCachedHiddenProcs = 0;
16602
16603        // First update the OOM adjustment for each of the
16604        // application processes based on their current state.
16605        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16606        int nextCachedAdj = curCachedAdj+1;
16607        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16608        int nextEmptyAdj = curEmptyAdj+2;
16609        for (int i=N-1; i>=0; i--) {
16610            ProcessRecord app = mLruProcesses.get(i);
16611            if (!app.killedByAm && app.thread != null) {
16612                app.procStateChanged = false;
16613                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16614
16615                // If we haven't yet assigned the final cached adj
16616                // to the process, do that now.
16617                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16618                    switch (app.curProcState) {
16619                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16620                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16621                            // This process is a cached process holding activities...
16622                            // assign it the next cached value for that type, and then
16623                            // step that cached level.
16624                            app.curRawAdj = curCachedAdj;
16625                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16626                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16627                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16628                                    + ")");
16629                            if (curCachedAdj != nextCachedAdj) {
16630                                stepCached++;
16631                                if (stepCached >= cachedFactor) {
16632                                    stepCached = 0;
16633                                    curCachedAdj = nextCachedAdj;
16634                                    nextCachedAdj += 2;
16635                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16636                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16637                                    }
16638                                }
16639                            }
16640                            break;
16641                        default:
16642                            // For everything else, assign next empty cached process
16643                            // level and bump that up.  Note that this means that
16644                            // long-running services that have dropped down to the
16645                            // cached level will be treated as empty (since their process
16646                            // state is still as a service), which is what we want.
16647                            app.curRawAdj = curEmptyAdj;
16648                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16649                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16650                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16651                                    + ")");
16652                            if (curEmptyAdj != nextEmptyAdj) {
16653                                stepEmpty++;
16654                                if (stepEmpty >= emptyFactor) {
16655                                    stepEmpty = 0;
16656                                    curEmptyAdj = nextEmptyAdj;
16657                                    nextEmptyAdj += 2;
16658                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16659                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16660                                    }
16661                                }
16662                            }
16663                            break;
16664                    }
16665                }
16666
16667                applyOomAdjLocked(app, TOP_APP, true, now);
16668
16669                // Count the number of process types.
16670                switch (app.curProcState) {
16671                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16672                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16673                        mNumCachedHiddenProcs++;
16674                        numCached++;
16675                        if (numCached > cachedProcessLimit) {
16676                            killUnneededProcessLocked(app, "cached #" + numCached);
16677                        }
16678                        break;
16679                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16680                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16681                                && app.lastActivityTime < oldTime) {
16682                            killUnneededProcessLocked(app, "empty for "
16683                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16684                                    / 1000) + "s");
16685                        } else {
16686                            numEmpty++;
16687                            if (numEmpty > emptyProcessLimit) {
16688                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16689                            }
16690                        }
16691                        break;
16692                    default:
16693                        mNumNonCachedProcs++;
16694                        break;
16695                }
16696
16697                if (app.isolated && app.services.size() <= 0) {
16698                    // If this is an isolated process, and there are no
16699                    // services running in it, then the process is no longer
16700                    // needed.  We agressively kill these because we can by
16701                    // definition not re-use the same process again, and it is
16702                    // good to avoid having whatever code was running in them
16703                    // left sitting around after no longer needed.
16704                    killUnneededProcessLocked(app, "isolated not needed");
16705                }
16706
16707                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16708                        && !app.killedByAm) {
16709                    numTrimming++;
16710                }
16711            }
16712        }
16713
16714        mNumServiceProcs = mNewNumServiceProcs;
16715
16716        // Now determine the memory trimming level of background processes.
16717        // Unfortunately we need to start at the back of the list to do this
16718        // properly.  We only do this if the number of background apps we
16719        // are managing to keep around is less than half the maximum we desire;
16720        // if we are keeping a good number around, we'll let them use whatever
16721        // memory they want.
16722        final int numCachedAndEmpty = numCached + numEmpty;
16723        int memFactor;
16724        if (numCached <= ProcessList.TRIM_CACHED_APPS
16725                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16726            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16727                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16728            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16729                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16730            } else {
16731                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16732            }
16733        } else {
16734            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16735        }
16736        // We always allow the memory level to go up (better).  We only allow it to go
16737        // down if we are in a state where that is allowed, *and* the total number of processes
16738        // has gone down since last time.
16739        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16740                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16741                + " last=" + mLastNumProcesses);
16742        if (memFactor > mLastMemoryLevel) {
16743            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16744                memFactor = mLastMemoryLevel;
16745                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16746            }
16747        }
16748        mLastMemoryLevel = memFactor;
16749        mLastNumProcesses = mLruProcesses.size();
16750        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16751        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16752        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16753            if (mLowRamStartTime == 0) {
16754                mLowRamStartTime = now;
16755            }
16756            int step = 0;
16757            int fgTrimLevel;
16758            switch (memFactor) {
16759                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16760                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16761                    break;
16762                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16763                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16764                    break;
16765                default:
16766                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16767                    break;
16768            }
16769            int factor = numTrimming/3;
16770            int minFactor = 2;
16771            if (mHomeProcess != null) minFactor++;
16772            if (mPreviousProcess != null) minFactor++;
16773            if (factor < minFactor) factor = minFactor;
16774            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16775            for (int i=N-1; i>=0; i--) {
16776                ProcessRecord app = mLruProcesses.get(i);
16777                if (allChanged || app.procStateChanged) {
16778                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16779                    app.procStateChanged = false;
16780                }
16781                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16782                        && !app.killedByAm) {
16783                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16784                        try {
16785                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16786                                    "Trimming memory of " + app.processName
16787                                    + " to " + curLevel);
16788                            app.thread.scheduleTrimMemory(curLevel);
16789                        } catch (RemoteException e) {
16790                        }
16791                        if (false) {
16792                            // For now we won't do this; our memory trimming seems
16793                            // to be good enough at this point that destroying
16794                            // activities causes more harm than good.
16795                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16796                                    && app != mHomeProcess && app != mPreviousProcess) {
16797                                // Need to do this on its own message because the stack may not
16798                                // be in a consistent state at this point.
16799                                // For these apps we will also finish their activities
16800                                // to help them free memory.
16801                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16802                            }
16803                        }
16804                    }
16805                    app.trimMemoryLevel = curLevel;
16806                    step++;
16807                    if (step >= factor) {
16808                        step = 0;
16809                        switch (curLevel) {
16810                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16811                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16812                                break;
16813                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16814                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16815                                break;
16816                        }
16817                    }
16818                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16819                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16820                            && app.thread != null) {
16821                        try {
16822                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16823                                    "Trimming memory of heavy-weight " + app.processName
16824                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16825                            app.thread.scheduleTrimMemory(
16826                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16827                        } catch (RemoteException e) {
16828                        }
16829                    }
16830                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16831                } else {
16832                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16833                            || app.systemNoUi) && app.pendingUiClean) {
16834                        // If this application is now in the background and it
16835                        // had done UI, then give it the special trim level to
16836                        // have it free UI resources.
16837                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16838                        if (app.trimMemoryLevel < level && app.thread != null) {
16839                            try {
16840                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16841                                        "Trimming memory of bg-ui " + app.processName
16842                                        + " to " + level);
16843                                app.thread.scheduleTrimMemory(level);
16844                            } catch (RemoteException e) {
16845                            }
16846                        }
16847                        app.pendingUiClean = false;
16848                    }
16849                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16850                        try {
16851                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16852                                    "Trimming memory of fg " + app.processName
16853                                    + " to " + fgTrimLevel);
16854                            app.thread.scheduleTrimMemory(fgTrimLevel);
16855                        } catch (RemoteException e) {
16856                        }
16857                    }
16858                    app.trimMemoryLevel = fgTrimLevel;
16859                }
16860            }
16861        } else {
16862            if (mLowRamStartTime != 0) {
16863                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16864                mLowRamStartTime = 0;
16865            }
16866            for (int i=N-1; i>=0; i--) {
16867                ProcessRecord app = mLruProcesses.get(i);
16868                if (allChanged || app.procStateChanged) {
16869                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16870                    app.procStateChanged = false;
16871                }
16872                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16873                        || app.systemNoUi) && app.pendingUiClean) {
16874                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16875                            && app.thread != null) {
16876                        try {
16877                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16878                                    "Trimming memory of ui hidden " + app.processName
16879                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16880                            app.thread.scheduleTrimMemory(
16881                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16882                        } catch (RemoteException e) {
16883                        }
16884                    }
16885                    app.pendingUiClean = false;
16886                }
16887                app.trimMemoryLevel = 0;
16888            }
16889        }
16890
16891        if (mAlwaysFinishActivities) {
16892            // Need to do this on its own message because the stack may not
16893            // be in a consistent state at this point.
16894            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16895        }
16896
16897        if (allChanged) {
16898            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16899        }
16900
16901        if (mProcessStats.shouldWriteNowLocked(now)) {
16902            mHandler.post(new Runnable() {
16903                @Override public void run() {
16904                    synchronized (ActivityManagerService.this) {
16905                        mProcessStats.writeStateAsyncLocked();
16906                    }
16907                }
16908            });
16909        }
16910
16911        if (DEBUG_OOM_ADJ) {
16912            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16913        }
16914    }
16915
16916    final void trimApplications() {
16917        synchronized (this) {
16918            int i;
16919
16920            // First remove any unused application processes whose package
16921            // has been removed.
16922            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16923                final ProcessRecord app = mRemovedProcesses.get(i);
16924                if (app.activities.size() == 0
16925                        && app.curReceiver == null && app.services.size() == 0) {
16926                    Slog.i(
16927                        TAG, "Exiting empty application process "
16928                        + app.processName + " ("
16929                        + (app.thread != null ? app.thread.asBinder() : null)
16930                        + ")\n");
16931                    if (app.pid > 0 && app.pid != MY_PID) {
16932                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16933                                app.processName, app.setAdj, "empty");
16934                        app.killedByAm = true;
16935                        Process.killProcessQuiet(app.pid);
16936                        Process.killProcessGroup(app.info.uid, app.pid);
16937                    } else {
16938                        try {
16939                            app.thread.scheduleExit();
16940                        } catch (Exception e) {
16941                            // Ignore exceptions.
16942                        }
16943                    }
16944                    cleanUpApplicationRecordLocked(app, false, true, -1);
16945                    mRemovedProcesses.remove(i);
16946
16947                    if (app.persistent) {
16948                        addAppLocked(app.info, false, null /* ABI override */);
16949                    }
16950                }
16951            }
16952
16953            // Now update the oom adj for all processes.
16954            updateOomAdjLocked();
16955        }
16956    }
16957
16958    /** This method sends the specified signal to each of the persistent apps */
16959    public void signalPersistentProcesses(int sig) throws RemoteException {
16960        if (sig != Process.SIGNAL_USR1) {
16961            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16962        }
16963
16964        synchronized (this) {
16965            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16966                    != PackageManager.PERMISSION_GRANTED) {
16967                throw new SecurityException("Requires permission "
16968                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16969            }
16970
16971            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16972                ProcessRecord r = mLruProcesses.get(i);
16973                if (r.thread != null && r.persistent) {
16974                    Process.sendSignal(r.pid, sig);
16975                }
16976            }
16977        }
16978    }
16979
16980    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16981        if (proc == null || proc == mProfileProc) {
16982            proc = mProfileProc;
16983            path = mProfileFile;
16984            profileType = mProfileType;
16985            clearProfilerLocked();
16986        }
16987        if (proc == null) {
16988            return;
16989        }
16990        try {
16991            proc.thread.profilerControl(false, path, null, profileType);
16992        } catch (RemoteException e) {
16993            throw new IllegalStateException("Process disappeared");
16994        }
16995    }
16996
16997    private void clearProfilerLocked() {
16998        if (mProfileFd != null) {
16999            try {
17000                mProfileFd.close();
17001            } catch (IOException e) {
17002            }
17003        }
17004        mProfileApp = null;
17005        mProfileProc = null;
17006        mProfileFile = null;
17007        mProfileType = 0;
17008        mAutoStopProfiler = false;
17009    }
17010
17011    public boolean profileControl(String process, int userId, boolean start,
17012            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
17013
17014        try {
17015            synchronized (this) {
17016                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17017                // its own permission.
17018                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17019                        != PackageManager.PERMISSION_GRANTED) {
17020                    throw new SecurityException("Requires permission "
17021                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17022                }
17023
17024                if (start && fd == null) {
17025                    throw new IllegalArgumentException("null fd");
17026                }
17027
17028                ProcessRecord proc = null;
17029                if (process != null) {
17030                    proc = findProcessLocked(process, userId, "profileControl");
17031                }
17032
17033                if (start && (proc == null || proc.thread == null)) {
17034                    throw new IllegalArgumentException("Unknown process: " + process);
17035                }
17036
17037                if (start) {
17038                    stopProfilerLocked(null, null, 0);
17039                    setProfileApp(proc.info, proc.processName, path, fd, false);
17040                    mProfileProc = proc;
17041                    mProfileType = profileType;
17042                    try {
17043                        fd = fd.dup();
17044                    } catch (IOException e) {
17045                        fd = null;
17046                    }
17047                    proc.thread.profilerControl(start, path, fd, profileType);
17048                    fd = null;
17049                    mProfileFd = null;
17050                } else {
17051                    stopProfilerLocked(proc, path, profileType);
17052                    if (fd != null) {
17053                        try {
17054                            fd.close();
17055                        } catch (IOException e) {
17056                        }
17057                    }
17058                }
17059
17060                return true;
17061            }
17062        } catch (RemoteException e) {
17063            throw new IllegalStateException("Process disappeared");
17064        } finally {
17065            if (fd != null) {
17066                try {
17067                    fd.close();
17068                } catch (IOException e) {
17069                }
17070            }
17071        }
17072    }
17073
17074    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17075        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17076                userId, true, ALLOW_FULL_ONLY, callName, null);
17077        ProcessRecord proc = null;
17078        try {
17079            int pid = Integer.parseInt(process);
17080            synchronized (mPidsSelfLocked) {
17081                proc = mPidsSelfLocked.get(pid);
17082            }
17083        } catch (NumberFormatException e) {
17084        }
17085
17086        if (proc == null) {
17087            ArrayMap<String, SparseArray<ProcessRecord>> all
17088                    = mProcessNames.getMap();
17089            SparseArray<ProcessRecord> procs = all.get(process);
17090            if (procs != null && procs.size() > 0) {
17091                proc = procs.valueAt(0);
17092                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17093                    for (int i=1; i<procs.size(); i++) {
17094                        ProcessRecord thisProc = procs.valueAt(i);
17095                        if (thisProc.userId == userId) {
17096                            proc = thisProc;
17097                            break;
17098                        }
17099                    }
17100                }
17101            }
17102        }
17103
17104        return proc;
17105    }
17106
17107    public boolean dumpHeap(String process, int userId, boolean managed,
17108            String path, ParcelFileDescriptor fd) throws RemoteException {
17109
17110        try {
17111            synchronized (this) {
17112                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17113                // its own permission (same as profileControl).
17114                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17115                        != PackageManager.PERMISSION_GRANTED) {
17116                    throw new SecurityException("Requires permission "
17117                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17118                }
17119
17120                if (fd == null) {
17121                    throw new IllegalArgumentException("null fd");
17122                }
17123
17124                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17125                if (proc == null || proc.thread == null) {
17126                    throw new IllegalArgumentException("Unknown process: " + process);
17127                }
17128
17129                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17130                if (!isDebuggable) {
17131                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17132                        throw new SecurityException("Process not debuggable: " + proc);
17133                    }
17134                }
17135
17136                proc.thread.dumpHeap(managed, path, fd);
17137                fd = null;
17138                return true;
17139            }
17140        } catch (RemoteException e) {
17141            throw new IllegalStateException("Process disappeared");
17142        } finally {
17143            if (fd != null) {
17144                try {
17145                    fd.close();
17146                } catch (IOException e) {
17147                }
17148            }
17149        }
17150    }
17151
17152    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17153    public void monitor() {
17154        synchronized (this) { }
17155    }
17156
17157    void onCoreSettingsChange(Bundle settings) {
17158        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17159            ProcessRecord processRecord = mLruProcesses.get(i);
17160            try {
17161                if (processRecord.thread != null) {
17162                    processRecord.thread.setCoreSettings(settings);
17163                }
17164            } catch (RemoteException re) {
17165                /* ignore */
17166            }
17167        }
17168    }
17169
17170    // Multi-user methods
17171
17172    /**
17173     * Start user, if its not already running, but don't bring it to foreground.
17174     */
17175    @Override
17176    public boolean startUserInBackground(final int userId) {
17177        return startUser(userId, /* foreground */ false);
17178    }
17179
17180    /**
17181     * Refreshes the list of users related to the current user when either a
17182     * user switch happens or when a new related user is started in the
17183     * background.
17184     */
17185    private void updateCurrentProfileIdsLocked() {
17186        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17187                mCurrentUserId, false /* enabledOnly */);
17188        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17189        for (int i = 0; i < currentProfileIds.length; i++) {
17190            currentProfileIds[i] = profiles.get(i).id;
17191        }
17192        mCurrentProfileIds = currentProfileIds;
17193
17194        synchronized (mUserProfileGroupIdsSelfLocked) {
17195            mUserProfileGroupIdsSelfLocked.clear();
17196            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17197            for (int i = 0; i < users.size(); i++) {
17198                UserInfo user = users.get(i);
17199                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17200                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17201                }
17202            }
17203        }
17204    }
17205
17206    private Set getProfileIdsLocked(int userId) {
17207        Set userIds = new HashSet<Integer>();
17208        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17209                userId, false /* enabledOnly */);
17210        for (UserInfo user : profiles) {
17211            userIds.add(Integer.valueOf(user.id));
17212        }
17213        return userIds;
17214    }
17215
17216    @Override
17217    public boolean switchUser(final int userId) {
17218        return startUser(userId, /* foregound */ true);
17219    }
17220
17221    private boolean startUser(final int userId, boolean foreground) {
17222        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17223                != PackageManager.PERMISSION_GRANTED) {
17224            String msg = "Permission Denial: switchUser() from pid="
17225                    + Binder.getCallingPid()
17226                    + ", uid=" + Binder.getCallingUid()
17227                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17228            Slog.w(TAG, msg);
17229            throw new SecurityException(msg);
17230        }
17231
17232        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17233
17234        final long ident = Binder.clearCallingIdentity();
17235        try {
17236            synchronized (this) {
17237                final int oldUserId = mCurrentUserId;
17238                if (oldUserId == userId) {
17239                    return true;
17240                }
17241
17242                mStackSupervisor.setLockTaskModeLocked(null, false);
17243
17244                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17245                if (userInfo == null) {
17246                    Slog.w(TAG, "No user info for user #" + userId);
17247                    return false;
17248                }
17249                if (foreground && userInfo.isManagedProfile()) {
17250                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17251                    return false;
17252                }
17253
17254                if (foreground) {
17255                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17256                            R.anim.screen_user_enter);
17257                }
17258
17259                boolean needStart = false;
17260
17261                // If the user we are switching to is not currently started, then
17262                // we need to start it now.
17263                if (mStartedUsers.get(userId) == null) {
17264                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17265                    updateStartedUserArrayLocked();
17266                    needStart = true;
17267                }
17268
17269                final Integer userIdInt = Integer.valueOf(userId);
17270                mUserLru.remove(userIdInt);
17271                mUserLru.add(userIdInt);
17272
17273                if (foreground) {
17274                    mCurrentUserId = userId;
17275                    updateCurrentProfileIdsLocked();
17276                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17277                    // Once the internal notion of the active user has switched, we lock the device
17278                    // with the option to show the user switcher on the keyguard.
17279                    mWindowManager.lockNow(null);
17280                } else {
17281                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17282                    updateCurrentProfileIdsLocked();
17283                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17284                    mUserLru.remove(currentUserIdInt);
17285                    mUserLru.add(currentUserIdInt);
17286                }
17287
17288                final UserStartedState uss = mStartedUsers.get(userId);
17289
17290                // Make sure user is in the started state.  If it is currently
17291                // stopping, we need to knock that off.
17292                if (uss.mState == UserStartedState.STATE_STOPPING) {
17293                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17294                    // so we can just fairly silently bring the user back from
17295                    // the almost-dead.
17296                    uss.mState = UserStartedState.STATE_RUNNING;
17297                    updateStartedUserArrayLocked();
17298                    needStart = true;
17299                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17300                    // This means ACTION_SHUTDOWN has been sent, so we will
17301                    // need to treat this as a new boot of the user.
17302                    uss.mState = UserStartedState.STATE_BOOTING;
17303                    updateStartedUserArrayLocked();
17304                    needStart = true;
17305                }
17306
17307                if (uss.mState == UserStartedState.STATE_BOOTING) {
17308                    // Booting up a new user, need to tell system services about it.
17309                    // Note that this is on the same handler as scheduling of broadcasts,
17310                    // which is important because it needs to go first.
17311                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17312                }
17313
17314                if (foreground) {
17315                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17316                            oldUserId));
17317                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17318                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17319                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17320                            oldUserId, userId, uss));
17321                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17322                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17323                }
17324
17325                if (needStart) {
17326                    // Send USER_STARTED broadcast
17327                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17328                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17329                            | Intent.FLAG_RECEIVER_FOREGROUND);
17330                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17331                    broadcastIntentLocked(null, null, intent,
17332                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17333                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17334                }
17335
17336                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17337                    if (userId != UserHandle.USER_OWNER) {
17338                        // Send PRE_BOOT_COMPLETED broadcasts for this new user
17339                        final ArrayList<ComponentName> doneReceivers
17340                                = new ArrayList<ComponentName>();
17341                        deliverPreBootCompleted(null, doneReceivers, userId);
17342
17343                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17344                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17345                        broadcastIntentLocked(null, null, intent, null,
17346                                new IIntentReceiver.Stub() {
17347                                    public void performReceive(Intent intent, int resultCode,
17348                                            String data, Bundle extras, boolean ordered,
17349                                            boolean sticky, int sendingUser) {
17350                                        userInitialized(uss, userId);
17351                                    }
17352                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17353                                true, false, MY_PID, Process.SYSTEM_UID,
17354                                userId);
17355                        uss.initializing = true;
17356                    } else {
17357                        getUserManagerLocked().makeInitialized(userInfo.id);
17358                    }
17359                }
17360
17361                if (foreground) {
17362                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17363                    if (homeInFront) {
17364                        startHomeActivityLocked(userId);
17365                    } else {
17366                        mStackSupervisor.resumeTopActivitiesLocked();
17367                    }
17368                    EventLogTags.writeAmSwitchUser(userId);
17369                    getUserManagerLocked().userForeground(userId);
17370                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17371                } else {
17372                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17373                }
17374
17375                if (needStart) {
17376                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17377                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17378                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17379                    broadcastIntentLocked(null, null, intent,
17380                            null, new IIntentReceiver.Stub() {
17381                                @Override
17382                                public void performReceive(Intent intent, int resultCode, String data,
17383                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17384                                        throws RemoteException {
17385                                }
17386                            }, 0, null, null,
17387                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17388                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17389                }
17390            }
17391        } finally {
17392            Binder.restoreCallingIdentity(ident);
17393        }
17394
17395        return true;
17396    }
17397
17398    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17399        long ident = Binder.clearCallingIdentity();
17400        try {
17401            Intent intent;
17402            if (oldUserId >= 0) {
17403                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17404                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17405                int count = profiles.size();
17406                for (int i = 0; i < count; i++) {
17407                    int profileUserId = profiles.get(i).id;
17408                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17409                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17410                            | Intent.FLAG_RECEIVER_FOREGROUND);
17411                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17412                    broadcastIntentLocked(null, null, intent,
17413                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17414                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17415                }
17416            }
17417            if (newUserId >= 0) {
17418                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17419                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17420                int count = profiles.size();
17421                for (int i = 0; i < count; i++) {
17422                    int profileUserId = profiles.get(i).id;
17423                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17424                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17425                            | Intent.FLAG_RECEIVER_FOREGROUND);
17426                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17427                    broadcastIntentLocked(null, null, intent,
17428                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17429                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17430                }
17431                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17432                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17433                        | Intent.FLAG_RECEIVER_FOREGROUND);
17434                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17435                broadcastIntentLocked(null, null, intent,
17436                        null, null, 0, null, null,
17437                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17438                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17439            }
17440        } finally {
17441            Binder.restoreCallingIdentity(ident);
17442        }
17443    }
17444
17445    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17446            final int newUserId) {
17447        final int N = mUserSwitchObservers.beginBroadcast();
17448        if (N > 0) {
17449            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17450                int mCount = 0;
17451                @Override
17452                public void sendResult(Bundle data) throws RemoteException {
17453                    synchronized (ActivityManagerService.this) {
17454                        if (mCurUserSwitchCallback == this) {
17455                            mCount++;
17456                            if (mCount == N) {
17457                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17458                            }
17459                        }
17460                    }
17461                }
17462            };
17463            synchronized (this) {
17464                uss.switching = true;
17465                mCurUserSwitchCallback = callback;
17466            }
17467            for (int i=0; i<N; i++) {
17468                try {
17469                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17470                            newUserId, callback);
17471                } catch (RemoteException e) {
17472                }
17473            }
17474        } else {
17475            synchronized (this) {
17476                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17477            }
17478        }
17479        mUserSwitchObservers.finishBroadcast();
17480    }
17481
17482    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17483        synchronized (this) {
17484            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17485            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17486        }
17487    }
17488
17489    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17490        mCurUserSwitchCallback = null;
17491        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17492        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17493                oldUserId, newUserId, uss));
17494    }
17495
17496    void userInitialized(UserStartedState uss, int newUserId) {
17497        completeSwitchAndInitalize(uss, newUserId, true, false);
17498    }
17499
17500    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17501        completeSwitchAndInitalize(uss, newUserId, false, true);
17502    }
17503
17504    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17505            boolean clearInitializing, boolean clearSwitching) {
17506        boolean unfrozen = false;
17507        synchronized (this) {
17508            if (clearInitializing) {
17509                uss.initializing = false;
17510                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17511            }
17512            if (clearSwitching) {
17513                uss.switching = false;
17514            }
17515            if (!uss.switching && !uss.initializing) {
17516                mWindowManager.stopFreezingScreen();
17517                unfrozen = true;
17518            }
17519        }
17520        if (unfrozen) {
17521            final int N = mUserSwitchObservers.beginBroadcast();
17522            for (int i=0; i<N; i++) {
17523                try {
17524                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17525                } catch (RemoteException e) {
17526                }
17527            }
17528            mUserSwitchObservers.finishBroadcast();
17529        }
17530    }
17531
17532    void scheduleStartProfilesLocked() {
17533        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17534            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17535                    DateUtils.SECOND_IN_MILLIS);
17536        }
17537    }
17538
17539    void startProfilesLocked() {
17540        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17541        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17542                mCurrentUserId, false /* enabledOnly */);
17543        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17544        for (UserInfo user : profiles) {
17545            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17546                    && user.id != mCurrentUserId) {
17547                toStart.add(user);
17548            }
17549        }
17550        final int n = toStart.size();
17551        int i = 0;
17552        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17553            startUserInBackground(toStart.get(i).id);
17554        }
17555        if (i < n) {
17556            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17557        }
17558    }
17559
17560    void finishUserBoot(UserStartedState uss) {
17561        synchronized (this) {
17562            if (uss.mState == UserStartedState.STATE_BOOTING
17563                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17564                uss.mState = UserStartedState.STATE_RUNNING;
17565                final int userId = uss.mHandle.getIdentifier();
17566                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17567                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17568                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17569                broadcastIntentLocked(null, null, intent,
17570                        null, null, 0, null, null,
17571                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17572                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17573            }
17574        }
17575    }
17576
17577    void finishUserSwitch(UserStartedState uss) {
17578        synchronized (this) {
17579            finishUserBoot(uss);
17580
17581            startProfilesLocked();
17582
17583            int num = mUserLru.size();
17584            int i = 0;
17585            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17586                Integer oldUserId = mUserLru.get(i);
17587                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17588                if (oldUss == null) {
17589                    // Shouldn't happen, but be sane if it does.
17590                    mUserLru.remove(i);
17591                    num--;
17592                    continue;
17593                }
17594                if (oldUss.mState == UserStartedState.STATE_STOPPING
17595                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17596                    // This user is already stopping, doesn't count.
17597                    num--;
17598                    i++;
17599                    continue;
17600                }
17601                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17602                    // Owner and current can't be stopped, but count as running.
17603                    i++;
17604                    continue;
17605                }
17606                // This is a user to be stopped.
17607                stopUserLocked(oldUserId, null);
17608                num--;
17609                i++;
17610            }
17611        }
17612    }
17613
17614    @Override
17615    public int stopUser(final int userId, final IStopUserCallback callback) {
17616        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17617                != PackageManager.PERMISSION_GRANTED) {
17618            String msg = "Permission Denial: switchUser() from pid="
17619                    + Binder.getCallingPid()
17620                    + ", uid=" + Binder.getCallingUid()
17621                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17622            Slog.w(TAG, msg);
17623            throw new SecurityException(msg);
17624        }
17625        if (userId <= 0) {
17626            throw new IllegalArgumentException("Can't stop primary user " + userId);
17627        }
17628        synchronized (this) {
17629            return stopUserLocked(userId, callback);
17630        }
17631    }
17632
17633    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17634        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17635        if (mCurrentUserId == userId) {
17636            return ActivityManager.USER_OP_IS_CURRENT;
17637        }
17638
17639        final UserStartedState uss = mStartedUsers.get(userId);
17640        if (uss == null) {
17641            // User is not started, nothing to do...  but we do need to
17642            // callback if requested.
17643            if (callback != null) {
17644                mHandler.post(new Runnable() {
17645                    @Override
17646                    public void run() {
17647                        try {
17648                            callback.userStopped(userId);
17649                        } catch (RemoteException e) {
17650                        }
17651                    }
17652                });
17653            }
17654            return ActivityManager.USER_OP_SUCCESS;
17655        }
17656
17657        if (callback != null) {
17658            uss.mStopCallbacks.add(callback);
17659        }
17660
17661        if (uss.mState != UserStartedState.STATE_STOPPING
17662                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17663            uss.mState = UserStartedState.STATE_STOPPING;
17664            updateStartedUserArrayLocked();
17665
17666            long ident = Binder.clearCallingIdentity();
17667            try {
17668                // We are going to broadcast ACTION_USER_STOPPING and then
17669                // once that is done send a final ACTION_SHUTDOWN and then
17670                // stop the user.
17671                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17672                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17673                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17674                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17675                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17676                // This is the result receiver for the final shutdown broadcast.
17677                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17678                    @Override
17679                    public void performReceive(Intent intent, int resultCode, String data,
17680                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17681                        finishUserStop(uss);
17682                    }
17683                };
17684                // This is the result receiver for the initial stopping broadcast.
17685                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17686                    @Override
17687                    public void performReceive(Intent intent, int resultCode, String data,
17688                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17689                        // On to the next.
17690                        synchronized (ActivityManagerService.this) {
17691                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17692                                // Whoops, we are being started back up.  Abort, abort!
17693                                return;
17694                            }
17695                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17696                        }
17697                        mBatteryStatsService.noteEvent(
17698                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17699                                Integer.toString(userId), userId);
17700                        mSystemServiceManager.stopUser(userId);
17701                        broadcastIntentLocked(null, null, shutdownIntent,
17702                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17703                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17704                    }
17705                };
17706                // Kick things off.
17707                broadcastIntentLocked(null, null, stoppingIntent,
17708                        null, stoppingReceiver, 0, null, null,
17709                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17710                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17711            } finally {
17712                Binder.restoreCallingIdentity(ident);
17713            }
17714        }
17715
17716        return ActivityManager.USER_OP_SUCCESS;
17717    }
17718
17719    void finishUserStop(UserStartedState uss) {
17720        final int userId = uss.mHandle.getIdentifier();
17721        boolean stopped;
17722        ArrayList<IStopUserCallback> callbacks;
17723        synchronized (this) {
17724            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17725            if (mStartedUsers.get(userId) != uss) {
17726                stopped = false;
17727            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17728                stopped = false;
17729            } else {
17730                stopped = true;
17731                // User can no longer run.
17732                mStartedUsers.remove(userId);
17733                mUserLru.remove(Integer.valueOf(userId));
17734                updateStartedUserArrayLocked();
17735
17736                // Clean up all state and processes associated with the user.
17737                // Kill all the processes for the user.
17738                forceStopUserLocked(userId, "finish user");
17739            }
17740
17741            // Explicitly remove the old information in mRecentTasks.
17742            removeRecentTasksForUserLocked(userId);
17743        }
17744
17745        for (int i=0; i<callbacks.size(); i++) {
17746            try {
17747                if (stopped) callbacks.get(i).userStopped(userId);
17748                else callbacks.get(i).userStopAborted(userId);
17749            } catch (RemoteException e) {
17750            }
17751        }
17752
17753        if (stopped) {
17754            mSystemServiceManager.cleanupUser(userId);
17755            synchronized (this) {
17756                mStackSupervisor.removeUserLocked(userId);
17757            }
17758        }
17759    }
17760
17761    @Override
17762    public UserInfo getCurrentUser() {
17763        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17764                != PackageManager.PERMISSION_GRANTED) && (
17765                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17766                != PackageManager.PERMISSION_GRANTED)) {
17767            String msg = "Permission Denial: getCurrentUser() from pid="
17768                    + Binder.getCallingPid()
17769                    + ", uid=" + Binder.getCallingUid()
17770                    + " requires " + INTERACT_ACROSS_USERS;
17771            Slog.w(TAG, msg);
17772            throw new SecurityException(msg);
17773        }
17774        synchronized (this) {
17775            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17776        }
17777    }
17778
17779    int getCurrentUserIdLocked() {
17780        return mCurrentUserId;
17781    }
17782
17783    @Override
17784    public boolean isUserRunning(int userId, boolean orStopped) {
17785        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17786                != PackageManager.PERMISSION_GRANTED) {
17787            String msg = "Permission Denial: isUserRunning() from pid="
17788                    + Binder.getCallingPid()
17789                    + ", uid=" + Binder.getCallingUid()
17790                    + " requires " + INTERACT_ACROSS_USERS;
17791            Slog.w(TAG, msg);
17792            throw new SecurityException(msg);
17793        }
17794        synchronized (this) {
17795            return isUserRunningLocked(userId, orStopped);
17796        }
17797    }
17798
17799    boolean isUserRunningLocked(int userId, boolean orStopped) {
17800        UserStartedState state = mStartedUsers.get(userId);
17801        if (state == null) {
17802            return false;
17803        }
17804        if (orStopped) {
17805            return true;
17806        }
17807        return state.mState != UserStartedState.STATE_STOPPING
17808                && state.mState != UserStartedState.STATE_SHUTDOWN;
17809    }
17810
17811    @Override
17812    public int[] getRunningUserIds() {
17813        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17814                != PackageManager.PERMISSION_GRANTED) {
17815            String msg = "Permission Denial: isUserRunning() from pid="
17816                    + Binder.getCallingPid()
17817                    + ", uid=" + Binder.getCallingUid()
17818                    + " requires " + INTERACT_ACROSS_USERS;
17819            Slog.w(TAG, msg);
17820            throw new SecurityException(msg);
17821        }
17822        synchronized (this) {
17823            return mStartedUserArray;
17824        }
17825    }
17826
17827    private void updateStartedUserArrayLocked() {
17828        int num = 0;
17829        for (int i=0; i<mStartedUsers.size();  i++) {
17830            UserStartedState uss = mStartedUsers.valueAt(i);
17831            // This list does not include stopping users.
17832            if (uss.mState != UserStartedState.STATE_STOPPING
17833                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17834                num++;
17835            }
17836        }
17837        mStartedUserArray = new int[num];
17838        num = 0;
17839        for (int i=0; i<mStartedUsers.size();  i++) {
17840            UserStartedState uss = mStartedUsers.valueAt(i);
17841            if (uss.mState != UserStartedState.STATE_STOPPING
17842                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17843                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17844                num++;
17845            }
17846        }
17847    }
17848
17849    @Override
17850    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17851        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17852                != PackageManager.PERMISSION_GRANTED) {
17853            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17854                    + Binder.getCallingPid()
17855                    + ", uid=" + Binder.getCallingUid()
17856                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17857            Slog.w(TAG, msg);
17858            throw new SecurityException(msg);
17859        }
17860
17861        mUserSwitchObservers.register(observer);
17862    }
17863
17864    @Override
17865    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17866        mUserSwitchObservers.unregister(observer);
17867    }
17868
17869    private boolean userExists(int userId) {
17870        if (userId == 0) {
17871            return true;
17872        }
17873        UserManagerService ums = getUserManagerLocked();
17874        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17875    }
17876
17877    int[] getUsersLocked() {
17878        UserManagerService ums = getUserManagerLocked();
17879        return ums != null ? ums.getUserIds() : new int[] { 0 };
17880    }
17881
17882    UserManagerService getUserManagerLocked() {
17883        if (mUserManager == null) {
17884            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17885            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17886        }
17887        return mUserManager;
17888    }
17889
17890    private int applyUserId(int uid, int userId) {
17891        return UserHandle.getUid(userId, uid);
17892    }
17893
17894    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17895        if (info == null) return null;
17896        ApplicationInfo newInfo = new ApplicationInfo(info);
17897        newInfo.uid = applyUserId(info.uid, userId);
17898        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17899                + info.packageName;
17900        return newInfo;
17901    }
17902
17903    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17904        if (aInfo == null
17905                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17906            return aInfo;
17907        }
17908
17909        ActivityInfo info = new ActivityInfo(aInfo);
17910        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17911        return info;
17912    }
17913
17914    private final class LocalService extends ActivityManagerInternal {
17915        @Override
17916        public void goingToSleep() {
17917            ActivityManagerService.this.goingToSleep();
17918        }
17919
17920        @Override
17921        public void wakingUp() {
17922            ActivityManagerService.this.wakingUp();
17923        }
17924
17925        @Override
17926        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
17927                String processName, String abiOverride, int uid, Runnable crashHandler) {
17928            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
17929                    processName, abiOverride, uid, crashHandler);
17930        }
17931    }
17932
17933    /**
17934     * An implementation of IAppTask, that allows an app to manage its own tasks via
17935     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17936     * only the process that calls getAppTasks() can call the AppTask methods.
17937     */
17938    class AppTaskImpl extends IAppTask.Stub {
17939        private int mTaskId;
17940        private int mCallingUid;
17941
17942        public AppTaskImpl(int taskId, int callingUid) {
17943            mTaskId = taskId;
17944            mCallingUid = callingUid;
17945        }
17946
17947        @Override
17948        public void finishAndRemoveTask() {
17949            // Ensure that we are called from the same process that created this AppTask
17950            if (mCallingUid != Binder.getCallingUid()) {
17951                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17952                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17953                return;
17954            }
17955
17956            synchronized (ActivityManagerService.this) {
17957                long origId = Binder.clearCallingIdentity();
17958                try {
17959                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17960                    if (tr != null) {
17961                        // Only kill the process if we are not a new document
17962                        int flags = tr.getBaseIntent().getFlags();
17963                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17964                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17965                        removeTaskByIdLocked(mTaskId,
17966                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17967                    }
17968                } finally {
17969                    Binder.restoreCallingIdentity(origId);
17970                }
17971            }
17972        }
17973
17974        @Override
17975        public ActivityManager.RecentTaskInfo getTaskInfo() {
17976            // Ensure that we are called from the same process that created this AppTask
17977            if (mCallingUid != Binder.getCallingUid()) {
17978                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17979                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17980                return null;
17981            }
17982
17983            synchronized (ActivityManagerService.this) {
17984                long origId = Binder.clearCallingIdentity();
17985                try {
17986                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17987                    if (tr != null) {
17988                        return createRecentTaskInfoFromTaskRecord(tr);
17989                    }
17990                } finally {
17991                    Binder.restoreCallingIdentity(origId);
17992                }
17993                return null;
17994            }
17995        }
17996    }
17997}
17998