ActivityManagerService.java revision 343f478241fab49c909b229d6876ff8405e7b0d5
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.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.os.storage.IMountService;
52import android.os.storage.StorageManager;
53import android.service.voice.IVoiceInteractionSession;
54import android.util.ArrayMap;
55import android.util.ArraySet;
56import android.util.SparseIntArray;
57
58import com.android.internal.R;
59import com.android.internal.annotations.GuardedBy;
60import com.android.internal.app.IAppOpsService;
61import com.android.internal.app.IVoiceInteractor;
62import com.android.internal.app.ProcessMap;
63import com.android.internal.app.ProcessStats;
64import com.android.internal.content.PackageMonitor;
65import com.android.internal.os.BackgroundThread;
66import com.android.internal.os.BatteryStatsImpl;
67import com.android.internal.os.ProcessCpuTracker;
68import com.android.internal.os.TransferPipe;
69import com.android.internal.os.Zygote;
70import com.android.internal.util.FastPrintWriter;
71import com.android.internal.util.FastXmlSerializer;
72import com.android.internal.util.MemInfoReader;
73import com.android.internal.util.Preconditions;
74import com.android.server.AppOpsService;
75import com.android.server.AttributeCache;
76import com.android.server.IntentResolver;
77import com.android.server.LocalServices;
78import com.android.server.ServiceThread;
79import com.android.server.SystemService;
80import com.android.server.SystemServiceManager;
81import com.android.server.Watchdog;
82import com.android.server.am.ActivityStack.ActivityState;
83import com.android.server.firewall.IntentFirewall;
84import com.android.server.pm.Installer;
85import com.android.server.pm.UserManagerService;
86import com.android.server.wm.AppTransition;
87import com.android.server.wm.WindowManagerService;
88import com.google.android.collect.Lists;
89import com.google.android.collect.Maps;
90
91import libcore.io.IoUtils;
92
93import org.xmlpull.v1.XmlPullParser;
94import org.xmlpull.v1.XmlPullParserException;
95import org.xmlpull.v1.XmlSerializer;
96
97import android.app.Activity;
98import android.app.ActivityManager;
99import android.app.ActivityManager.RunningTaskInfo;
100import android.app.ActivityManager.StackInfo;
101import android.app.ActivityManagerInternal;
102import android.app.ActivityManagerNative;
103import android.app.ActivityOptions;
104import android.app.ActivityThread;
105import android.app.AlertDialog;
106import android.app.AppGlobals;
107import android.app.ApplicationErrorReport;
108import android.app.Dialog;
109import android.app.IActivityController;
110import android.app.IApplicationThread;
111import android.app.IInstrumentationWatcher;
112import android.app.INotificationManager;
113import android.app.IProcessObserver;
114import android.app.IServiceConnection;
115import android.app.IStopUserCallback;
116import android.app.IUiAutomationConnection;
117import android.app.IUserSwitchObserver;
118import android.app.Instrumentation;
119import android.app.Notification;
120import android.app.NotificationManager;
121import android.app.PendingIntent;
122import android.app.backup.IBackupManager;
123import android.content.ActivityNotFoundException;
124import android.content.BroadcastReceiver;
125import android.content.ClipData;
126import android.content.ComponentCallbacks2;
127import android.content.ComponentName;
128import android.content.ContentProvider;
129import android.content.ContentResolver;
130import android.content.Context;
131import android.content.DialogInterface;
132import android.content.IContentProvider;
133import android.content.IIntentReceiver;
134import android.content.IIntentSender;
135import android.content.Intent;
136import android.content.IntentFilter;
137import android.content.IntentSender;
138import android.content.pm.ActivityInfo;
139import android.content.pm.ApplicationInfo;
140import android.content.pm.ConfigurationInfo;
141import android.content.pm.IPackageDataObserver;
142import android.content.pm.IPackageManager;
143import android.content.pm.InstrumentationInfo;
144import android.content.pm.PackageInfo;
145import android.content.pm.PackageManager;
146import android.content.pm.ParceledListSlice;
147import android.content.pm.UserInfo;
148import android.content.pm.PackageManager.NameNotFoundException;
149import android.content.pm.PathPermission;
150import android.content.pm.ProviderInfo;
151import android.content.pm.ResolveInfo;
152import android.content.pm.ServiceInfo;
153import android.content.res.CompatibilityInfo;
154import android.content.res.Configuration;
155import android.net.Proxy;
156import android.net.ProxyInfo;
157import android.net.Uri;
158import android.os.Binder;
159import android.os.Build;
160import android.os.Bundle;
161import android.os.Debug;
162import android.os.DropBoxManager;
163import android.os.Environment;
164import android.os.FactoryTest;
165import android.os.FileObserver;
166import android.os.FileUtils;
167import android.os.Handler;
168import android.os.IBinder;
169import android.os.IPermissionController;
170import android.os.IRemoteCallback;
171import android.os.IUserManager;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.Process;
177import android.os.RemoteCallbackList;
178import android.os.RemoteException;
179import android.os.SELinux;
180import android.os.ServiceManager;
181import android.os.StrictMode;
182import android.os.SystemClock;
183import android.os.SystemProperties;
184import android.os.UpdateLock;
185import android.os.UserHandle;
186import android.os.UserManager;
187import android.provider.Settings;
188import android.text.format.DateUtils;
189import android.text.format.Time;
190import android.util.AtomicFile;
191import android.util.EventLog;
192import android.util.Log;
193import android.util.Pair;
194import android.util.PrintWriterPrinter;
195import android.util.Slog;
196import android.util.SparseArray;
197import android.util.TimeUtils;
198import android.util.Xml;
199import android.view.Gravity;
200import android.view.LayoutInflater;
201import android.view.View;
202import android.view.WindowManager;
203import dalvik.system.VMRuntime;
204
205import java.io.BufferedInputStream;
206import java.io.BufferedOutputStream;
207import java.io.DataInputStream;
208import java.io.DataOutputStream;
209import java.io.File;
210import java.io.FileDescriptor;
211import java.io.FileInputStream;
212import java.io.FileNotFoundException;
213import java.io.FileOutputStream;
214import java.io.IOException;
215import java.io.InputStreamReader;
216import java.io.PrintWriter;
217import java.io.StringWriter;
218import java.lang.ref.WeakReference;
219import java.util.ArrayList;
220import java.util.Arrays;
221import java.util.Collections;
222import java.util.Comparator;
223import java.util.HashMap;
224import java.util.HashSet;
225import java.util.Iterator;
226import java.util.List;
227import java.util.Locale;
228import java.util.Map;
229import java.util.Set;
230import java.util.concurrent.atomic.AtomicBoolean;
231import java.util.concurrent.atomic.AtomicLong;
232
233public final class ActivityManagerService extends ActivityManagerNative
234        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
235
236    private static final String USER_DATA_DIR = "/data/user/";
237    // File that stores last updated system version and called preboot receivers
238    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
239
240    static final String TAG = "ActivityManager";
241    static final String TAG_MU = "ActivityManagerServiceMU";
242    static final boolean DEBUG = false;
243    static final boolean localLOGV = DEBUG;
244    static final boolean DEBUG_BACKUP = localLOGV || false;
245    static final boolean DEBUG_BROADCAST = localLOGV || false;
246    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
247    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
248    static final boolean DEBUG_CLEANUP = localLOGV || false;
249    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
250    static final boolean DEBUG_FOCUS = false;
251    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
252    static final boolean DEBUG_MU = localLOGV || false;
253    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
254    static final boolean DEBUG_LRU = localLOGV || false;
255    static final boolean DEBUG_PAUSE = localLOGV || false;
256    static final boolean DEBUG_POWER = localLOGV || false;
257    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
258    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
259    static final boolean DEBUG_PROCESSES = localLOGV || false;
260    static final boolean DEBUG_PROVIDER = localLOGV || false;
261    static final boolean DEBUG_RESULTS = localLOGV || false;
262    static final boolean DEBUG_SERVICE = localLOGV || false;
263    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
264    static final boolean DEBUG_STACK = localLOGV || false;
265    static final boolean DEBUG_SWITCH = localLOGV || false;
266    static final boolean DEBUG_TASKS = localLOGV || false;
267    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
268    static final boolean DEBUG_TRANSITION = localLOGV || false;
269    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
270    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
271    static final boolean DEBUG_VISBILITY = localLOGV || false;
272    static final boolean DEBUG_PSS = localLOGV || false;
273    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
274    static final boolean DEBUG_RECENTS = localLOGV || false;
275    static final boolean VALIDATE_TOKENS = false;
276    static final boolean SHOW_ACTIVITY_START_TIME = true;
277
278    // Control over CPU and battery monitoring.
279    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
280    static final boolean MONITOR_CPU_USAGE = true;
281    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
282    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
283    static final boolean MONITOR_THREAD_CPU_USAGE = false;
284
285    // The flags that are set for all calls we make to the package manager.
286    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
287
288    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
289
290    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
291
292    // Maximum number recent bitmaps to keep in memory.
293    static final int MAX_RECENT_BITMAPS = 5;
294
295    // Amount of time after a call to stopAppSwitches() during which we will
296    // prevent further untrusted switches from happening.
297    static final long APP_SWITCH_DELAY_TIME = 5*1000;
298
299    // How long we wait for a launched process to attach to the activity manager
300    // before we decide it's never going to come up for real.
301    static final int PROC_START_TIMEOUT = 10*1000;
302
303    // How long we wait for a launched process to attach to the activity manager
304    // before we decide it's never going to come up for real, when the process was
305    // started with a wrapper for instrumentation (such as Valgrind) because it
306    // could take much longer than usual.
307    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
308
309    // How long to wait after going idle before forcing apps to GC.
310    static final int GC_TIMEOUT = 5*1000;
311
312    // The minimum amount of time between successive GC requests for a process.
313    static final int GC_MIN_INTERVAL = 60*1000;
314
315    // The minimum amount of time between successive PSS requests for a process.
316    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
317
318    // The minimum amount of time between successive PSS requests for a process
319    // when the request is due to the memory state being lowered.
320    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
321
322    // The rate at which we check for apps using excessive power -- 15 mins.
323    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
324
325    // The minimum sample duration we will allow before deciding we have
326    // enough data on wake locks to start killing things.
327    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
328
329    // The minimum sample duration we will allow before deciding we have
330    // enough data on CPU usage to start killing things.
331    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
332
333    // How long we allow a receiver to run before giving up on it.
334    static final int BROADCAST_FG_TIMEOUT = 10*1000;
335    static final int BROADCAST_BG_TIMEOUT = 60*1000;
336
337    // How long we wait until we timeout on key dispatching.
338    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
339
340    // How long we wait until we timeout on key dispatching during instrumentation.
341    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
342
343    // Amount of time we wait for observers to handle a user switch before
344    // giving up on them and unfreezing the screen.
345    static final int USER_SWITCH_TIMEOUT = 2*1000;
346
347    // Maximum number of users we allow to be running at a time.
348    static final int MAX_RUNNING_USERS = 3;
349
350    // How long to wait in getAssistContextExtras for the activity and foreground services
351    // to respond with the result.
352    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
353
354    // Maximum number of persisted Uri grants a package is allowed
355    static final int MAX_PERSISTED_URI_GRANTS = 128;
356
357    static final int MY_PID = Process.myPid();
358
359    static final String[] EMPTY_STRING_ARRAY = new String[0];
360
361    // How many bytes to write into the dropbox log before truncating
362    static final int DROPBOX_MAX_SIZE = 256 * 1024;
363
364    // Access modes for handleIncomingUser.
365    static final int ALLOW_NON_FULL = 0;
366    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
367    static final int ALLOW_FULL_ONLY = 2;
368
369    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
370
371    /** All system services */
372    SystemServiceManager mSystemServiceManager;
373
374    private Installer mInstaller;
375
376    /** Run all ActivityStacks through this */
377    ActivityStackSupervisor mStackSupervisor;
378
379    public IntentFirewall mIntentFirewall;
380
381    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
382    // default actuion automatically.  Important for devices without direct input
383    // devices.
384    private boolean mShowDialogs = true;
385
386    BroadcastQueue mFgBroadcastQueue;
387    BroadcastQueue mBgBroadcastQueue;
388    // Convenient for easy iteration over the queues. Foreground is first
389    // so that dispatch of foreground broadcasts gets precedence.
390    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
391
392    BroadcastQueue broadcastQueueForIntent(Intent intent) {
393        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
394        if (DEBUG_BACKGROUND_BROADCAST) {
395            Slog.i(TAG, "Broadcast intent " + intent + " on "
396                    + (isFg ? "foreground" : "background")
397                    + " queue");
398        }
399        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
400    }
401
402    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
403        for (BroadcastQueue queue : mBroadcastQueues) {
404            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
405            if (r != null) {
406                return r;
407            }
408        }
409        return null;
410    }
411
412    /**
413     * Activity we have told the window manager to have key focus.
414     */
415    ActivityRecord mFocusedActivity = null;
416
417    /**
418     * List of intents that were used to start the most recent tasks.
419     */
420    ArrayList<TaskRecord> mRecentTasks;
421    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
422
423    /**
424     * For addAppTask: cached of the last activity component that was added.
425     */
426    ComponentName mLastAddedTaskComponent;
427
428    /**
429     * For addAppTask: cached of the last activity uid that was added.
430     */
431    int mLastAddedTaskUid;
432
433    /**
434     * For addAppTask: cached of the last ActivityInfo that was added.
435     */
436    ActivityInfo mLastAddedTaskActivity;
437
438    public class PendingAssistExtras extends Binder implements Runnable {
439        public final ActivityRecord activity;
440        public final Bundle extras;
441        public final Intent intent;
442        public final String hint;
443        public final int userHandle;
444        public boolean haveResult = false;
445        public Bundle result = null;
446        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
447                String _hint, int _userHandle) {
448            activity = _activity;
449            extras = _extras;
450            intent = _intent;
451            hint = _hint;
452            userHandle = _userHandle;
453        }
454        @Override
455        public void run() {
456            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
457            synchronized (this) {
458                haveResult = true;
459                notifyAll();
460            }
461        }
462    }
463
464    final ArrayList<PendingAssistExtras> mPendingAssistExtras
465            = new ArrayList<PendingAssistExtras>();
466
467    /**
468     * Process management.
469     */
470    final ProcessList mProcessList = new ProcessList();
471
472    /**
473     * All of the applications we currently have running organized by name.
474     * The keys are strings of the application package name (as
475     * returned by the package manager), and the keys are ApplicationRecord
476     * objects.
477     */
478    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
479
480    /**
481     * Tracking long-term execution of processes to look for abuse and other
482     * bad app behavior.
483     */
484    final ProcessStatsService mProcessStats;
485
486    /**
487     * The currently running isolated processes.
488     */
489    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
490
491    /**
492     * Counter for assigning isolated process uids, to avoid frequently reusing the
493     * same ones.
494     */
495    int mNextIsolatedProcessUid = 0;
496
497    /**
498     * The currently running heavy-weight process, if any.
499     */
500    ProcessRecord mHeavyWeightProcess = null;
501
502    /**
503     * The last time that various processes have crashed.
504     */
505    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
506
507    /**
508     * Information about a process that is currently marked as bad.
509     */
510    static final class BadProcessInfo {
511        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
512            this.time = time;
513            this.shortMsg = shortMsg;
514            this.longMsg = longMsg;
515            this.stack = stack;
516        }
517
518        final long time;
519        final String shortMsg;
520        final String longMsg;
521        final String stack;
522    }
523
524    /**
525     * Set of applications that we consider to be bad, and will reject
526     * incoming broadcasts from (which the user has no control over).
527     * Processes are added to this set when they have crashed twice within
528     * a minimum amount of time; they are removed from it when they are
529     * later restarted (hopefully due to some user action).  The value is the
530     * time it was added to the list.
531     */
532    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
533
534    /**
535     * All of the processes we currently have running organized by pid.
536     * The keys are the pid running the application.
537     *
538     * <p>NOTE: This object is protected by its own lock, NOT the global
539     * activity manager lock!
540     */
541    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
542
543    /**
544     * All of the processes that have been forced to be foreground.  The key
545     * is the pid of the caller who requested it (we hold a death
546     * link on it).
547     */
548    abstract class ForegroundToken implements IBinder.DeathRecipient {
549        int pid;
550        IBinder token;
551    }
552    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
553
554    /**
555     * List of records for processes that someone had tried to start before the
556     * system was ready.  We don't start them at that point, but ensure they
557     * are started by the time booting is complete.
558     */
559    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
560
561    /**
562     * List of persistent applications that are in the process
563     * of being started.
564     */
565    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
566
567    /**
568     * Processes that are being forcibly torn down.
569     */
570    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
571
572    /**
573     * List of running applications, sorted by recent usage.
574     * The first entry in the list is the least recently used.
575     */
576    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
577
578    /**
579     * Where in mLruProcesses that the processes hosting activities start.
580     */
581    int mLruProcessActivityStart = 0;
582
583    /**
584     * Where in mLruProcesses that the processes hosting services start.
585     * This is after (lower index) than mLruProcessesActivityStart.
586     */
587    int mLruProcessServiceStart = 0;
588
589    /**
590     * List of processes that should gc as soon as things are idle.
591     */
592    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
593
594    /**
595     * Processes we want to collect PSS data from.
596     */
597    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
598
599    /**
600     * Last time we requested PSS data of all processes.
601     */
602    long mLastFullPssTime = SystemClock.uptimeMillis();
603
604    /**
605     * If set, the next time we collect PSS data we should do a full collection
606     * with data from native processes and the kernel.
607     */
608    boolean mFullPssPending = false;
609
610    /**
611     * This is the process holding what we currently consider to be
612     * the "home" activity.
613     */
614    ProcessRecord mHomeProcess;
615
616    /**
617     * This is the process holding the activity the user last visited that
618     * is in a different process from the one they are currently in.
619     */
620    ProcessRecord mPreviousProcess;
621
622    /**
623     * The time at which the previous process was last visible.
624     */
625    long mPreviousProcessVisibleTime;
626
627    /**
628     * Which uses have been started, so are allowed to run code.
629     */
630    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
631
632    /**
633     * LRU list of history of current users.  Most recently current is at the end.
634     */
635    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
636
637    /**
638     * Constant array of the users that are currently started.
639     */
640    int[] mStartedUserArray = new int[] { 0 };
641
642    /**
643     * Registered observers of the user switching mechanics.
644     */
645    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
646            = new RemoteCallbackList<IUserSwitchObserver>();
647
648    /**
649     * Currently active user switch.
650     */
651    Object mCurUserSwitchCallback;
652
653    /**
654     * Packages that the user has asked to have run in screen size
655     * compatibility mode instead of filling the screen.
656     */
657    final CompatModePackages mCompatModePackages;
658
659    /**
660     * Set of IntentSenderRecord objects that are currently active.
661     */
662    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
663            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
664
665    /**
666     * Fingerprints (hashCode()) of stack traces that we've
667     * already logged DropBox entries for.  Guarded by itself.  If
668     * something (rogue user app) forces this over
669     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
670     */
671    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
672    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
673
674    /**
675     * Strict Mode background batched logging state.
676     *
677     * The string buffer is guarded by itself, and its lock is also
678     * used to determine if another batched write is already
679     * in-flight.
680     */
681    private final StringBuilder mStrictModeBuffer = new StringBuilder();
682
683    /**
684     * Keeps track of all IIntentReceivers that have been registered for
685     * broadcasts.  Hash keys are the receiver IBinder, hash value is
686     * a ReceiverList.
687     */
688    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
689            new HashMap<IBinder, ReceiverList>();
690
691    /**
692     * Resolver for broadcast intents to registered receivers.
693     * Holds BroadcastFilter (subclass of IntentFilter).
694     */
695    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
696            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
697        @Override
698        protected boolean allowFilterResult(
699                BroadcastFilter filter, List<BroadcastFilter> dest) {
700            IBinder target = filter.receiverList.receiver.asBinder();
701            for (int i=dest.size()-1; i>=0; i--) {
702                if (dest.get(i).receiverList.receiver.asBinder() == target) {
703                    return false;
704                }
705            }
706            return true;
707        }
708
709        @Override
710        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
711            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
712                    || userId == filter.owningUserId) {
713                return super.newResult(filter, match, userId);
714            }
715            return null;
716        }
717
718        @Override
719        protected BroadcastFilter[] newArray(int size) {
720            return new BroadcastFilter[size];
721        }
722
723        @Override
724        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
725            return packageName.equals(filter.packageName);
726        }
727    };
728
729    /**
730     * State of all active sticky broadcasts per user.  Keys are the action of the
731     * sticky Intent, values are an ArrayList of all broadcasted intents with
732     * that action (which should usually be one).  The SparseArray is keyed
733     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
734     * for stickies that are sent to all users.
735     */
736    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
737            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
738
739    final ActiveServices mServices;
740
741    /**
742     * Backup/restore process management
743     */
744    String mBackupAppName = null;
745    BackupRecord mBackupTarget = null;
746
747    final ProviderMap mProviderMap;
748
749    /**
750     * List of content providers who have clients waiting for them.  The
751     * application is currently being launched and the provider will be
752     * removed from this list once it is published.
753     */
754    final ArrayList<ContentProviderRecord> mLaunchingProviders
755            = new ArrayList<ContentProviderRecord>();
756
757    /**
758     * File storing persisted {@link #mGrantedUriPermissions}.
759     */
760    private final AtomicFile mGrantFile;
761
762    /** XML constants used in {@link #mGrantFile} */
763    private static final String TAG_URI_GRANTS = "uri-grants";
764    private static final String TAG_URI_GRANT = "uri-grant";
765    private static final String ATTR_USER_HANDLE = "userHandle";
766    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
767    private static final String ATTR_TARGET_USER_ID = "targetUserId";
768    private static final String ATTR_SOURCE_PKG = "sourcePkg";
769    private static final String ATTR_TARGET_PKG = "targetPkg";
770    private static final String ATTR_URI = "uri";
771    private static final String ATTR_MODE_FLAGS = "modeFlags";
772    private static final String ATTR_CREATED_TIME = "createdTime";
773    private static final String ATTR_PREFIX = "prefix";
774
775    /**
776     * Global set of specific {@link Uri} permissions that have been granted.
777     * This optimized lookup structure maps from {@link UriPermission#targetUid}
778     * to {@link UriPermission#uri} to {@link UriPermission}.
779     */
780    @GuardedBy("this")
781    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
782            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
783
784    public static class GrantUri {
785        public final int sourceUserId;
786        public final Uri uri;
787        public boolean prefix;
788
789        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
790            this.sourceUserId = sourceUserId;
791            this.uri = uri;
792            this.prefix = prefix;
793        }
794
795        @Override
796        public int hashCode() {
797            return toString().hashCode();
798        }
799
800        @Override
801        public boolean equals(Object o) {
802            if (o instanceof GrantUri) {
803                GrantUri other = (GrantUri) o;
804                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
805                        && prefix == other.prefix;
806            }
807            return false;
808        }
809
810        @Override
811        public String toString() {
812            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
813            if (prefix) result += " [prefix]";
814            return result;
815        }
816
817        public String toSafeString() {
818            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
819            if (prefix) result += " [prefix]";
820            return result;
821        }
822
823        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
824            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
825                    ContentProvider.getUriWithoutUserId(uri), false);
826        }
827    }
828
829    CoreSettingsObserver mCoreSettingsObserver;
830
831    /**
832     * Thread-local storage used to carry caller permissions over through
833     * indirect content-provider access.
834     */
835    private class Identity {
836        public int pid;
837        public int uid;
838
839        Identity(int _pid, int _uid) {
840            pid = _pid;
841            uid = _uid;
842        }
843    }
844
845    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
846
847    /**
848     * All information we have collected about the runtime performance of
849     * any user id that can impact battery performance.
850     */
851    final BatteryStatsService mBatteryStatsService;
852
853    /**
854     * Information about component usage
855     */
856    UsageStatsManagerInternal mUsageStatsService;
857
858    /**
859     * Information about and control over application operations
860     */
861    final AppOpsService mAppOpsService;
862
863    /**
864     * Save recent tasks information across reboots.
865     */
866    final TaskPersister mTaskPersister;
867
868    /**
869     * Current configuration information.  HistoryRecord objects are given
870     * a reference to this object to indicate which configuration they are
871     * currently running in, so this object must be kept immutable.
872     */
873    Configuration mConfiguration = new Configuration();
874
875    /**
876     * Current sequencing integer of the configuration, for skipping old
877     * configurations.
878     */
879    int mConfigurationSeq = 0;
880
881    /**
882     * Hardware-reported OpenGLES version.
883     */
884    final int GL_ES_VERSION;
885
886    /**
887     * List of initialization arguments to pass to all processes when binding applications to them.
888     * For example, references to the commonly used services.
889     */
890    HashMap<String, IBinder> mAppBindArgs;
891
892    /**
893     * Temporary to avoid allocations.  Protected by main lock.
894     */
895    final StringBuilder mStringBuilder = new StringBuilder(256);
896
897    /**
898     * Used to control how we initialize the service.
899     */
900    ComponentName mTopComponent;
901    String mTopAction = Intent.ACTION_MAIN;
902    String mTopData;
903    boolean mProcessesReady = false;
904    boolean mSystemReady = false;
905    boolean mBooting = false;
906    boolean mCallFinishBooting = false;
907    boolean mBootAnimationComplete = false;
908    boolean mWaitingUpdate = false;
909    boolean mDidUpdate = false;
910    boolean mOnBattery = false;
911    boolean mLaunchWarningShown = false;
912
913    Context mContext;
914
915    int mFactoryTest;
916
917    boolean mCheckedForSetup;
918
919    /**
920     * The time at which we will allow normal application switches again,
921     * after a call to {@link #stopAppSwitches()}.
922     */
923    long mAppSwitchesAllowedTime;
924
925    /**
926     * This is set to true after the first switch after mAppSwitchesAllowedTime
927     * is set; any switches after that will clear the time.
928     */
929    boolean mDidAppSwitch;
930
931    /**
932     * Last time (in realtime) at which we checked for power usage.
933     */
934    long mLastPowerCheckRealtime;
935
936    /**
937     * Last time (in uptime) at which we checked for power usage.
938     */
939    long mLastPowerCheckUptime;
940
941    /**
942     * Set while we are wanting to sleep, to prevent any
943     * activities from being started/resumed.
944     */
945    private boolean mSleeping = false;
946
947    /**
948     * Set while we are running a voice interaction.  This overrides
949     * sleeping while it is active.
950     */
951    private boolean mRunningVoice = false;
952
953    /**
954     * State of external calls telling us if the device is asleep.
955     */
956    private boolean mWentToSleep = false;
957
958    /**
959     * State of external call telling us if the lock screen is shown.
960     */
961    private boolean mLockScreenShown = false;
962
963    /**
964     * Set if we are shutting down the system, similar to sleeping.
965     */
966    boolean mShuttingDown = false;
967
968    /**
969     * Current sequence id for oom_adj computation traversal.
970     */
971    int mAdjSeq = 0;
972
973    /**
974     * Current sequence id for process LRU updating.
975     */
976    int mLruSeq = 0;
977
978    /**
979     * Keep track of the non-cached/empty process we last found, to help
980     * determine how to distribute cached/empty processes next time.
981     */
982    int mNumNonCachedProcs = 0;
983
984    /**
985     * Keep track of the number of cached hidden procs, to balance oom adj
986     * distribution between those and empty procs.
987     */
988    int mNumCachedHiddenProcs = 0;
989
990    /**
991     * Keep track of the number of service processes we last found, to
992     * determine on the next iteration which should be B services.
993     */
994    int mNumServiceProcs = 0;
995    int mNewNumAServiceProcs = 0;
996    int mNewNumServiceProcs = 0;
997
998    /**
999     * Allow the current computed overall memory level of the system to go down?
1000     * This is set to false when we are killing processes for reasons other than
1001     * memory management, so that the now smaller process list will not be taken as
1002     * an indication that memory is tighter.
1003     */
1004    boolean mAllowLowerMemLevel = false;
1005
1006    /**
1007     * The last computed memory level, for holding when we are in a state that
1008     * processes are going away for other reasons.
1009     */
1010    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1011
1012    /**
1013     * The last total number of process we have, to determine if changes actually look
1014     * like a shrinking number of process due to lower RAM.
1015     */
1016    int mLastNumProcesses;
1017
1018    /**
1019     * The uptime of the last time we performed idle maintenance.
1020     */
1021    long mLastIdleTime = SystemClock.uptimeMillis();
1022
1023    /**
1024     * Total time spent with RAM that has been added in the past since the last idle time.
1025     */
1026    long mLowRamTimeSinceLastIdle = 0;
1027
1028    /**
1029     * If RAM is currently low, when that horrible situation started.
1030     */
1031    long mLowRamStartTime = 0;
1032
1033    /**
1034     * For reporting to battery stats the current top application.
1035     */
1036    private String mCurResumedPackage = null;
1037    private int mCurResumedUid = -1;
1038
1039    /**
1040     * For reporting to battery stats the apps currently running foreground
1041     * service.  The ProcessMap is package/uid tuples; each of these contain
1042     * an array of the currently foreground processes.
1043     */
1044    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1045            = new ProcessMap<ArrayList<ProcessRecord>>();
1046
1047    /**
1048     * This is set if we had to do a delayed dexopt of an app before launching
1049     * it, to increase the ANR timeouts in that case.
1050     */
1051    boolean mDidDexOpt;
1052
1053    /**
1054     * Set if the systemServer made a call to enterSafeMode.
1055     */
1056    boolean mSafeMode;
1057
1058    String mDebugApp = null;
1059    boolean mWaitForDebugger = false;
1060    boolean mDebugTransient = false;
1061    String mOrigDebugApp = null;
1062    boolean mOrigWaitForDebugger = false;
1063    boolean mAlwaysFinishActivities = false;
1064    IActivityController mController = null;
1065    String mProfileApp = null;
1066    ProcessRecord mProfileProc = null;
1067    String mProfileFile;
1068    ParcelFileDescriptor mProfileFd;
1069    int mSamplingInterval = 0;
1070    boolean mAutoStopProfiler = false;
1071    int mProfileType = 0;
1072    String mOpenGlTraceApp = null;
1073
1074    static class ProcessChangeItem {
1075        static final int CHANGE_ACTIVITIES = 1<<0;
1076        static final int CHANGE_PROCESS_STATE = 1<<1;
1077        int changes;
1078        int uid;
1079        int pid;
1080        int processState;
1081        boolean foregroundActivities;
1082    }
1083
1084    final RemoteCallbackList<IProcessObserver> mProcessObservers
1085            = new RemoteCallbackList<IProcessObserver>();
1086    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1087
1088    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1089            = new ArrayList<ProcessChangeItem>();
1090    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1091            = new ArrayList<ProcessChangeItem>();
1092
1093    /**
1094     * Runtime CPU use collection thread.  This object's lock is used to
1095     * perform synchronization with the thread (notifying it to run).
1096     */
1097    final Thread mProcessCpuThread;
1098
1099    /**
1100     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1101     * Must acquire this object's lock when accessing it.
1102     * NOTE: this lock will be held while doing long operations (trawling
1103     * through all processes in /proc), so it should never be acquired by
1104     * any critical paths such as when holding the main activity manager lock.
1105     */
1106    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1107            MONITOR_THREAD_CPU_USAGE);
1108    final AtomicLong mLastCpuTime = new AtomicLong(0);
1109    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1110
1111    long mLastWriteTime = 0;
1112
1113    /**
1114     * Used to retain an update lock when the foreground activity is in
1115     * immersive mode.
1116     */
1117    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1118
1119    /**
1120     * Set to true after the system has finished booting.
1121     */
1122    boolean mBooted = false;
1123
1124    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1125    int mProcessLimitOverride = -1;
1126
1127    WindowManagerService mWindowManager;
1128
1129    final ActivityThread mSystemThread;
1130
1131    // Holds the current foreground user's id
1132    int mCurrentUserId = 0;
1133    // Holds the target user's id during a user switch
1134    int mTargetUserId = UserHandle.USER_NULL;
1135    // If there are multiple profiles for the current user, their ids are here
1136    // Currently only the primary user can have managed profiles
1137    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1138
1139    /**
1140     * Mapping from each known user ID to the profile group ID it is associated with.
1141     */
1142    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1143
1144    private UserManagerService mUserManager;
1145
1146    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1147        final ProcessRecord mApp;
1148        final int mPid;
1149        final IApplicationThread mAppThread;
1150
1151        AppDeathRecipient(ProcessRecord app, int pid,
1152                IApplicationThread thread) {
1153            if (localLOGV) Slog.v(
1154                TAG, "New death recipient " + this
1155                + " for thread " + thread.asBinder());
1156            mApp = app;
1157            mPid = pid;
1158            mAppThread = thread;
1159        }
1160
1161        @Override
1162        public void binderDied() {
1163            if (localLOGV) Slog.v(
1164                TAG, "Death received in " + this
1165                + " for thread " + mAppThread.asBinder());
1166            synchronized(ActivityManagerService.this) {
1167                appDiedLocked(mApp, mPid, mAppThread);
1168            }
1169        }
1170    }
1171
1172    static final int SHOW_ERROR_MSG = 1;
1173    static final int SHOW_NOT_RESPONDING_MSG = 2;
1174    static final int SHOW_FACTORY_ERROR_MSG = 3;
1175    static final int UPDATE_CONFIGURATION_MSG = 4;
1176    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1177    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1178    static final int SERVICE_TIMEOUT_MSG = 12;
1179    static final int UPDATE_TIME_ZONE = 13;
1180    static final int SHOW_UID_ERROR_MSG = 14;
1181    static final int IM_FEELING_LUCKY_MSG = 15;
1182    static final int PROC_START_TIMEOUT_MSG = 20;
1183    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1184    static final int KILL_APPLICATION_MSG = 22;
1185    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1186    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1187    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1188    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1189    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1190    static final int CLEAR_DNS_CACHE_MSG = 28;
1191    static final int UPDATE_HTTP_PROXY_MSG = 29;
1192    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1193    static final int DISPATCH_PROCESSES_CHANGED = 31;
1194    static final int DISPATCH_PROCESS_DIED = 32;
1195    static final int REPORT_MEM_USAGE_MSG = 33;
1196    static final int REPORT_USER_SWITCH_MSG = 34;
1197    static final int CONTINUE_USER_SWITCH_MSG = 35;
1198    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1199    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1200    static final int PERSIST_URI_GRANTS_MSG = 38;
1201    static final int REQUEST_ALL_PSS_MSG = 39;
1202    static final int START_PROFILES_MSG = 40;
1203    static final int UPDATE_TIME = 41;
1204    static final int SYSTEM_USER_START_MSG = 42;
1205    static final int SYSTEM_USER_CURRENT_MSG = 43;
1206    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1207    static final int FINISH_BOOTING_MSG = 45;
1208    static final int START_USER_SWITCH_MSG = 46;
1209    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1210
1211    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1212    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1213    static final int FIRST_COMPAT_MODE_MSG = 300;
1214    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1215
1216    AlertDialog mUidAlert;
1217    CompatModeDialog mCompatModeDialog;
1218    long mLastMemUsageReportTime = 0;
1219
1220    private LockToAppRequestDialog mLockToAppRequest;
1221
1222    /**
1223     * Flag whether the current user is a "monkey", i.e. whether
1224     * the UI is driven by a UI automation tool.
1225     */
1226    private boolean mUserIsMonkey;
1227
1228    /** Flag whether the device has a Recents UI */
1229    boolean mHasRecents;
1230
1231    /** The dimensions of the thumbnails in the Recents UI. */
1232    int mThumbnailWidth;
1233    int mThumbnailHeight;
1234
1235    final ServiceThread mHandlerThread;
1236    final MainHandler mHandler;
1237
1238    final class MainHandler extends Handler {
1239        public MainHandler(Looper looper) {
1240            super(looper, null, true);
1241        }
1242
1243        @Override
1244        public void handleMessage(Message msg) {
1245            switch (msg.what) {
1246            case SHOW_ERROR_MSG: {
1247                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1248                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1249                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1250                synchronized (ActivityManagerService.this) {
1251                    ProcessRecord proc = (ProcessRecord)data.get("app");
1252                    AppErrorResult res = (AppErrorResult) data.get("result");
1253                    if (proc != null && proc.crashDialog != null) {
1254                        Slog.e(TAG, "App already has crash dialog: " + proc);
1255                        if (res != null) {
1256                            res.set(0);
1257                        }
1258                        return;
1259                    }
1260                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1261                            >= Process.FIRST_APPLICATION_UID
1262                            && proc.pid != MY_PID);
1263                    for (int userId : mCurrentProfileIds) {
1264                        isBackground &= (proc.userId != userId);
1265                    }
1266                    if (isBackground && !showBackground) {
1267                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1268                        if (res != null) {
1269                            res.set(0);
1270                        }
1271                        return;
1272                    }
1273                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1274                        Dialog d = new AppErrorDialog(mContext,
1275                                ActivityManagerService.this, res, proc);
1276                        d.show();
1277                        proc.crashDialog = d;
1278                    } else {
1279                        // The device is asleep, so just pretend that the user
1280                        // saw a crash dialog and hit "force quit".
1281                        if (res != null) {
1282                            res.set(0);
1283                        }
1284                    }
1285                }
1286
1287                ensureBootCompleted();
1288            } break;
1289            case SHOW_NOT_RESPONDING_MSG: {
1290                synchronized (ActivityManagerService.this) {
1291                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1292                    ProcessRecord proc = (ProcessRecord)data.get("app");
1293                    if (proc != null && proc.anrDialog != null) {
1294                        Slog.e(TAG, "App already has anr dialog: " + proc);
1295                        return;
1296                    }
1297
1298                    Intent intent = new Intent("android.intent.action.ANR");
1299                    if (!mProcessesReady) {
1300                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1301                                | Intent.FLAG_RECEIVER_FOREGROUND);
1302                    }
1303                    broadcastIntentLocked(null, null, intent,
1304                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1305                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1306
1307                    if (mShowDialogs) {
1308                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1309                                mContext, proc, (ActivityRecord)data.get("activity"),
1310                                msg.arg1 != 0);
1311                        d.show();
1312                        proc.anrDialog = d;
1313                    } else {
1314                        // Just kill the app if there is no dialog to be shown.
1315                        killAppAtUsersRequest(proc, null);
1316                    }
1317                }
1318
1319                ensureBootCompleted();
1320            } break;
1321            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1322                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1323                synchronized (ActivityManagerService.this) {
1324                    ProcessRecord proc = (ProcessRecord) data.get("app");
1325                    if (proc == null) {
1326                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1327                        break;
1328                    }
1329                    if (proc.crashDialog != null) {
1330                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1331                        return;
1332                    }
1333                    AppErrorResult res = (AppErrorResult) data.get("result");
1334                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1335                        Dialog d = new StrictModeViolationDialog(mContext,
1336                                ActivityManagerService.this, res, proc);
1337                        d.show();
1338                        proc.crashDialog = d;
1339                    } else {
1340                        // The device is asleep, so just pretend that the user
1341                        // saw a crash dialog and hit "force quit".
1342                        res.set(0);
1343                    }
1344                }
1345                ensureBootCompleted();
1346            } break;
1347            case SHOW_FACTORY_ERROR_MSG: {
1348                Dialog d = new FactoryErrorDialog(
1349                    mContext, msg.getData().getCharSequence("msg"));
1350                d.show();
1351                ensureBootCompleted();
1352            } break;
1353            case UPDATE_CONFIGURATION_MSG: {
1354                final ContentResolver resolver = mContext.getContentResolver();
1355                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1356            } break;
1357            case GC_BACKGROUND_PROCESSES_MSG: {
1358                synchronized (ActivityManagerService.this) {
1359                    performAppGcsIfAppropriateLocked();
1360                }
1361            } break;
1362            case WAIT_FOR_DEBUGGER_MSG: {
1363                synchronized (ActivityManagerService.this) {
1364                    ProcessRecord app = (ProcessRecord)msg.obj;
1365                    if (msg.arg1 != 0) {
1366                        if (!app.waitedForDebugger) {
1367                            Dialog d = new AppWaitingForDebuggerDialog(
1368                                    ActivityManagerService.this,
1369                                    mContext, app);
1370                            app.waitDialog = d;
1371                            app.waitedForDebugger = true;
1372                            d.show();
1373                        }
1374                    } else {
1375                        if (app.waitDialog != null) {
1376                            app.waitDialog.dismiss();
1377                            app.waitDialog = null;
1378                        }
1379                    }
1380                }
1381            } break;
1382            case SERVICE_TIMEOUT_MSG: {
1383                if (mDidDexOpt) {
1384                    mDidDexOpt = false;
1385                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1386                    nmsg.obj = msg.obj;
1387                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1388                    return;
1389                }
1390                mServices.serviceTimeout((ProcessRecord)msg.obj);
1391            } break;
1392            case UPDATE_TIME_ZONE: {
1393                synchronized (ActivityManagerService.this) {
1394                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1395                        ProcessRecord r = mLruProcesses.get(i);
1396                        if (r.thread != null) {
1397                            try {
1398                                r.thread.updateTimeZone();
1399                            } catch (RemoteException ex) {
1400                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1401                            }
1402                        }
1403                    }
1404                }
1405            } break;
1406            case CLEAR_DNS_CACHE_MSG: {
1407                synchronized (ActivityManagerService.this) {
1408                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1409                        ProcessRecord r = mLruProcesses.get(i);
1410                        if (r.thread != null) {
1411                            try {
1412                                r.thread.clearDnsCache();
1413                            } catch (RemoteException ex) {
1414                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1415                            }
1416                        }
1417                    }
1418                }
1419            } break;
1420            case UPDATE_HTTP_PROXY_MSG: {
1421                ProxyInfo proxy = (ProxyInfo)msg.obj;
1422                String host = "";
1423                String port = "";
1424                String exclList = "";
1425                Uri pacFileUrl = Uri.EMPTY;
1426                if (proxy != null) {
1427                    host = proxy.getHost();
1428                    port = Integer.toString(proxy.getPort());
1429                    exclList = proxy.getExclusionListAsString();
1430                    pacFileUrl = proxy.getPacFileUrl();
1431                }
1432                synchronized (ActivityManagerService.this) {
1433                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1434                        ProcessRecord r = mLruProcesses.get(i);
1435                        if (r.thread != null) {
1436                            try {
1437                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1438                            } catch (RemoteException ex) {
1439                                Slog.w(TAG, "Failed to update http proxy for: " +
1440                                        r.info.processName);
1441                            }
1442                        }
1443                    }
1444                }
1445            } break;
1446            case SHOW_UID_ERROR_MSG: {
1447                String title = "System UIDs Inconsistent";
1448                String text = "UIDs on the system are inconsistent, you need to wipe your"
1449                        + " data partition or your device will be unstable.";
1450                Log.e(TAG, title + ": " + text);
1451                if (mShowDialogs) {
1452                    // XXX This is a temporary dialog, no need to localize.
1453                    AlertDialog d = new BaseErrorDialog(mContext);
1454                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1455                    d.setCancelable(false);
1456                    d.setTitle(title);
1457                    d.setMessage(text);
1458                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1459                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1460                    mUidAlert = d;
1461                    d.show();
1462                }
1463            } break;
1464            case IM_FEELING_LUCKY_MSG: {
1465                if (mUidAlert != null) {
1466                    mUidAlert.dismiss();
1467                    mUidAlert = null;
1468                }
1469            } break;
1470            case PROC_START_TIMEOUT_MSG: {
1471                if (mDidDexOpt) {
1472                    mDidDexOpt = false;
1473                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1474                    nmsg.obj = msg.obj;
1475                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1476                    return;
1477                }
1478                ProcessRecord app = (ProcessRecord)msg.obj;
1479                synchronized (ActivityManagerService.this) {
1480                    processStartTimedOutLocked(app);
1481                }
1482            } break;
1483            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1484                synchronized (ActivityManagerService.this) {
1485                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1486                }
1487            } break;
1488            case KILL_APPLICATION_MSG: {
1489                synchronized (ActivityManagerService.this) {
1490                    int appid = msg.arg1;
1491                    boolean restart = (msg.arg2 == 1);
1492                    Bundle bundle = (Bundle)msg.obj;
1493                    String pkg = bundle.getString("pkg");
1494                    String reason = bundle.getString("reason");
1495                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1496                            false, UserHandle.USER_ALL, reason);
1497                }
1498            } break;
1499            case FINALIZE_PENDING_INTENT_MSG: {
1500                ((PendingIntentRecord)msg.obj).completeFinalize();
1501            } break;
1502            case POST_HEAVY_NOTIFICATION_MSG: {
1503                INotificationManager inm = NotificationManager.getService();
1504                if (inm == null) {
1505                    return;
1506                }
1507
1508                ActivityRecord root = (ActivityRecord)msg.obj;
1509                ProcessRecord process = root.app;
1510                if (process == null) {
1511                    return;
1512                }
1513
1514                try {
1515                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1516                    String text = mContext.getString(R.string.heavy_weight_notification,
1517                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1518                    Notification notification = new Notification();
1519                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1520                    notification.when = 0;
1521                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1522                    notification.tickerText = text;
1523                    notification.defaults = 0; // please be quiet
1524                    notification.sound = null;
1525                    notification.vibrate = null;
1526                    notification.color = mContext.getResources().getColor(
1527                            com.android.internal.R.color.system_notification_accent_color);
1528                    notification.setLatestEventInfo(context, text,
1529                            mContext.getText(R.string.heavy_weight_notification_detail),
1530                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1531                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1532                                    new UserHandle(root.userId)));
1533
1534                    try {
1535                        int[] outId = new int[1];
1536                        inm.enqueueNotificationWithTag("android", "android", null,
1537                                R.string.heavy_weight_notification,
1538                                notification, outId, root.userId);
1539                    } catch (RuntimeException e) {
1540                        Slog.w(ActivityManagerService.TAG,
1541                                "Error showing notification for heavy-weight app", e);
1542                    } catch (RemoteException e) {
1543                    }
1544                } catch (NameNotFoundException e) {
1545                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1546                }
1547            } break;
1548            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1549                INotificationManager inm = NotificationManager.getService();
1550                if (inm == null) {
1551                    return;
1552                }
1553                try {
1554                    inm.cancelNotificationWithTag("android", null,
1555                            R.string.heavy_weight_notification,  msg.arg1);
1556                } catch (RuntimeException e) {
1557                    Slog.w(ActivityManagerService.TAG,
1558                            "Error canceling notification for service", e);
1559                } catch (RemoteException e) {
1560                }
1561            } break;
1562            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1563                synchronized (ActivityManagerService.this) {
1564                    checkExcessivePowerUsageLocked(true);
1565                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1566                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1567                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1568                }
1569            } break;
1570            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1571                synchronized (ActivityManagerService.this) {
1572                    ActivityRecord ar = (ActivityRecord)msg.obj;
1573                    if (mCompatModeDialog != null) {
1574                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1575                                ar.info.applicationInfo.packageName)) {
1576                            return;
1577                        }
1578                        mCompatModeDialog.dismiss();
1579                        mCompatModeDialog = null;
1580                    }
1581                    if (ar != null && false) {
1582                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1583                                ar.packageName)) {
1584                            int mode = mCompatModePackages.computeCompatModeLocked(
1585                                    ar.info.applicationInfo);
1586                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1587                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1588                                mCompatModeDialog = new CompatModeDialog(
1589                                        ActivityManagerService.this, mContext,
1590                                        ar.info.applicationInfo);
1591                                mCompatModeDialog.show();
1592                            }
1593                        }
1594                    }
1595                }
1596                break;
1597            }
1598            case DISPATCH_PROCESSES_CHANGED: {
1599                dispatchProcessesChanged();
1600                break;
1601            }
1602            case DISPATCH_PROCESS_DIED: {
1603                final int pid = msg.arg1;
1604                final int uid = msg.arg2;
1605                dispatchProcessDied(pid, uid);
1606                break;
1607            }
1608            case REPORT_MEM_USAGE_MSG: {
1609                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1610                Thread thread = new Thread() {
1611                    @Override public void run() {
1612                        final SparseArray<ProcessMemInfo> infoMap
1613                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1614                        for (int i=0, N=memInfos.size(); i<N; i++) {
1615                            ProcessMemInfo mi = memInfos.get(i);
1616                            infoMap.put(mi.pid, mi);
1617                        }
1618                        updateCpuStatsNow();
1619                        synchronized (mProcessCpuTracker) {
1620                            final int N = mProcessCpuTracker.countStats();
1621                            for (int i=0; i<N; i++) {
1622                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1623                                if (st.vsize > 0) {
1624                                    long pss = Debug.getPss(st.pid, null);
1625                                    if (pss > 0) {
1626                                        if (infoMap.indexOfKey(st.pid) < 0) {
1627                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1628                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1629                                            mi.pss = pss;
1630                                            memInfos.add(mi);
1631                                        }
1632                                    }
1633                                }
1634                            }
1635                        }
1636
1637                        long totalPss = 0;
1638                        for (int i=0, N=memInfos.size(); i<N; i++) {
1639                            ProcessMemInfo mi = memInfos.get(i);
1640                            if (mi.pss == 0) {
1641                                mi.pss = Debug.getPss(mi.pid, null);
1642                            }
1643                            totalPss += mi.pss;
1644                        }
1645                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1646                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1647                                if (lhs.oomAdj != rhs.oomAdj) {
1648                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1649                                }
1650                                if (lhs.pss != rhs.pss) {
1651                                    return lhs.pss < rhs.pss ? 1 : -1;
1652                                }
1653                                return 0;
1654                            }
1655                        });
1656
1657                        StringBuilder tag = new StringBuilder(128);
1658                        StringBuilder stack = new StringBuilder(128);
1659                        tag.append("Low on memory -- ");
1660                        appendMemBucket(tag, totalPss, "total", false);
1661                        appendMemBucket(stack, totalPss, "total", true);
1662
1663                        StringBuilder logBuilder = new StringBuilder(1024);
1664                        logBuilder.append("Low on memory:\n");
1665
1666                        boolean firstLine = true;
1667                        int lastOomAdj = Integer.MIN_VALUE;
1668                        for (int i=0, N=memInfos.size(); i<N; i++) {
1669                            ProcessMemInfo mi = memInfos.get(i);
1670
1671                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1672                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1673                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1674                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1675                                if (lastOomAdj != mi.oomAdj) {
1676                                    lastOomAdj = mi.oomAdj;
1677                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1678                                        tag.append(" / ");
1679                                    }
1680                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1681                                        if (firstLine) {
1682                                            stack.append(":");
1683                                            firstLine = false;
1684                                        }
1685                                        stack.append("\n\t at ");
1686                                    } else {
1687                                        stack.append("$");
1688                                    }
1689                                } else {
1690                                    tag.append(" ");
1691                                    stack.append("$");
1692                                }
1693                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1694                                    appendMemBucket(tag, mi.pss, mi.name, false);
1695                                }
1696                                appendMemBucket(stack, mi.pss, mi.name, true);
1697                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1698                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1699                                    stack.append("(");
1700                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1701                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1702                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1703                                            stack.append(":");
1704                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1705                                        }
1706                                    }
1707                                    stack.append(")");
1708                                }
1709                            }
1710
1711                            logBuilder.append("  ");
1712                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1713                            logBuilder.append(' ');
1714                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1715                            logBuilder.append(' ');
1716                            ProcessList.appendRamKb(logBuilder, mi.pss);
1717                            logBuilder.append(" kB: ");
1718                            logBuilder.append(mi.name);
1719                            logBuilder.append(" (");
1720                            logBuilder.append(mi.pid);
1721                            logBuilder.append(") ");
1722                            logBuilder.append(mi.adjType);
1723                            logBuilder.append('\n');
1724                            if (mi.adjReason != null) {
1725                                logBuilder.append("                      ");
1726                                logBuilder.append(mi.adjReason);
1727                                logBuilder.append('\n');
1728                            }
1729                        }
1730
1731                        logBuilder.append("           ");
1732                        ProcessList.appendRamKb(logBuilder, totalPss);
1733                        logBuilder.append(" kB: TOTAL\n");
1734
1735                        long[] infos = new long[Debug.MEMINFO_COUNT];
1736                        Debug.getMemInfo(infos);
1737                        logBuilder.append("  MemInfo: ");
1738                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1739                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1740                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1741                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1742                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1743                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1744                            logBuilder.append("  ZRAM: ");
1745                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1746                            logBuilder.append(" kB RAM, ");
1747                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1748                            logBuilder.append(" kB swap total, ");
1749                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1750                            logBuilder.append(" kB swap free\n");
1751                        }
1752                        Slog.i(TAG, logBuilder.toString());
1753
1754                        StringBuilder dropBuilder = new StringBuilder(1024);
1755                        /*
1756                        StringWriter oomSw = new StringWriter();
1757                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1758                        StringWriter catSw = new StringWriter();
1759                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1760                        String[] emptyArgs = new String[] { };
1761                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1762                        oomPw.flush();
1763                        String oomString = oomSw.toString();
1764                        */
1765                        dropBuilder.append(stack);
1766                        dropBuilder.append('\n');
1767                        dropBuilder.append('\n');
1768                        dropBuilder.append(logBuilder);
1769                        dropBuilder.append('\n');
1770                        /*
1771                        dropBuilder.append(oomString);
1772                        dropBuilder.append('\n');
1773                        */
1774                        StringWriter catSw = new StringWriter();
1775                        synchronized (ActivityManagerService.this) {
1776                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1777                            String[] emptyArgs = new String[] { };
1778                            catPw.println();
1779                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1780                            catPw.println();
1781                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1782                                    false, false, null);
1783                            catPw.println();
1784                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1785                            catPw.flush();
1786                        }
1787                        dropBuilder.append(catSw.toString());
1788                        addErrorToDropBox("lowmem", null, "system_server", null,
1789                                null, tag.toString(), dropBuilder.toString(), null, null);
1790                        //Slog.i(TAG, "Sent to dropbox:");
1791                        //Slog.i(TAG, dropBuilder.toString());
1792                        synchronized (ActivityManagerService.this) {
1793                            long now = SystemClock.uptimeMillis();
1794                            if (mLastMemUsageReportTime < now) {
1795                                mLastMemUsageReportTime = now;
1796                            }
1797                        }
1798                    }
1799                };
1800                thread.start();
1801                break;
1802            }
1803            case START_USER_SWITCH_MSG: {
1804                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1805                break;
1806            }
1807            case REPORT_USER_SWITCH_MSG: {
1808                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1809                break;
1810            }
1811            case CONTINUE_USER_SWITCH_MSG: {
1812                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1813                break;
1814            }
1815            case USER_SWITCH_TIMEOUT_MSG: {
1816                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1817                break;
1818            }
1819            case IMMERSIVE_MODE_LOCK_MSG: {
1820                final boolean nextState = (msg.arg1 != 0);
1821                if (mUpdateLock.isHeld() != nextState) {
1822                    if (DEBUG_IMMERSIVE) {
1823                        final ActivityRecord r = (ActivityRecord) msg.obj;
1824                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1825                    }
1826                    if (nextState) {
1827                        mUpdateLock.acquire();
1828                    } else {
1829                        mUpdateLock.release();
1830                    }
1831                }
1832                break;
1833            }
1834            case PERSIST_URI_GRANTS_MSG: {
1835                writeGrantedUriPermissions();
1836                break;
1837            }
1838            case REQUEST_ALL_PSS_MSG: {
1839                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1840                break;
1841            }
1842            case START_PROFILES_MSG: {
1843                synchronized (ActivityManagerService.this) {
1844                    startProfilesLocked();
1845                }
1846                break;
1847            }
1848            case UPDATE_TIME: {
1849                synchronized (ActivityManagerService.this) {
1850                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1851                        ProcessRecord r = mLruProcesses.get(i);
1852                        if (r.thread != null) {
1853                            try {
1854                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1855                            } catch (RemoteException ex) {
1856                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1857                            }
1858                        }
1859                    }
1860                }
1861                break;
1862            }
1863            case SYSTEM_USER_START_MSG: {
1864                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1865                        Integer.toString(msg.arg1), msg.arg1);
1866                mSystemServiceManager.startUser(msg.arg1);
1867                break;
1868            }
1869            case SYSTEM_USER_CURRENT_MSG: {
1870                mBatteryStatsService.noteEvent(
1871                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1872                        Integer.toString(msg.arg2), msg.arg2);
1873                mBatteryStatsService.noteEvent(
1874                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1875                        Integer.toString(msg.arg1), msg.arg1);
1876                mSystemServiceManager.switchUser(msg.arg1);
1877                mLockToAppRequest.clearPrompt();
1878                break;
1879            }
1880            case ENTER_ANIMATION_COMPLETE_MSG: {
1881                synchronized (ActivityManagerService.this) {
1882                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1883                    if (r != null && r.app != null && r.app.thread != null) {
1884                        try {
1885                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1886                        } catch (RemoteException e) {
1887                        }
1888                    }
1889                }
1890                break;
1891            }
1892            case FINISH_BOOTING_MSG: {
1893                if (msg.arg1 != 0) {
1894                    finishBooting();
1895                }
1896                if (msg.arg2 != 0) {
1897                    enableScreenAfterBoot();
1898                }
1899                break;
1900            }
1901            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1902                try {
1903                    Locale l = (Locale) msg.obj;
1904                    IBinder service = ServiceManager.getService("mount");
1905                    IMountService mountService = IMountService.Stub.asInterface(service);
1906                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1907                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1908                } catch (RemoteException e) {
1909                    Log.e(TAG, "Error storing locale for decryption UI", e);
1910                }
1911                break;
1912            }
1913            }
1914        }
1915    };
1916
1917    static final int COLLECT_PSS_BG_MSG = 1;
1918
1919    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1920        @Override
1921        public void handleMessage(Message msg) {
1922            switch (msg.what) {
1923            case COLLECT_PSS_BG_MSG: {
1924                long start = SystemClock.uptimeMillis();
1925                MemInfoReader memInfo = null;
1926                synchronized (ActivityManagerService.this) {
1927                    if (mFullPssPending) {
1928                        mFullPssPending = false;
1929                        memInfo = new MemInfoReader();
1930                    }
1931                }
1932                if (memInfo != null) {
1933                    updateCpuStatsNow();
1934                    long nativeTotalPss = 0;
1935                    synchronized (mProcessCpuTracker) {
1936                        final int N = mProcessCpuTracker.countStats();
1937                        for (int j=0; j<N; j++) {
1938                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1939                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1940                                // This is definitely an application process; skip it.
1941                                continue;
1942                            }
1943                            synchronized (mPidsSelfLocked) {
1944                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1945                                    // This is one of our own processes; skip it.
1946                                    continue;
1947                                }
1948                            }
1949                            nativeTotalPss += Debug.getPss(st.pid, null);
1950                        }
1951                    }
1952                    memInfo.readMemInfo();
1953                    synchronized (ActivityManagerService.this) {
1954                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1955                                + (SystemClock.uptimeMillis()-start) + "ms");
1956                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1957                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1958                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1959                                        +memInfo.getSlabSizeKb(),
1960                                nativeTotalPss);
1961                    }
1962                }
1963
1964                int i=0, num=0;
1965                long[] tmp = new long[1];
1966                do {
1967                    ProcessRecord proc;
1968                    int procState;
1969                    int pid;
1970                    synchronized (ActivityManagerService.this) {
1971                        if (i >= mPendingPssProcesses.size()) {
1972                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1973                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1974                            mPendingPssProcesses.clear();
1975                            return;
1976                        }
1977                        proc = mPendingPssProcesses.get(i);
1978                        procState = proc.pssProcState;
1979                        if (proc.thread != null && procState == proc.setProcState) {
1980                            pid = proc.pid;
1981                        } else {
1982                            proc = null;
1983                            pid = 0;
1984                        }
1985                        i++;
1986                    }
1987                    if (proc != null) {
1988                        long pss = Debug.getPss(pid, tmp);
1989                        synchronized (ActivityManagerService.this) {
1990                            if (proc.thread != null && proc.setProcState == procState
1991                                    && proc.pid == pid) {
1992                                num++;
1993                                proc.lastPssTime = SystemClock.uptimeMillis();
1994                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1995                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1996                                        + ": " + pss + " lastPss=" + proc.lastPss
1997                                        + " state=" + ProcessList.makeProcStateString(procState));
1998                                if (proc.initialIdlePss == 0) {
1999                                    proc.initialIdlePss = pss;
2000                                }
2001                                proc.lastPss = pss;
2002                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
2003                                    proc.lastCachedPss = pss;
2004                                }
2005                            }
2006                        }
2007                    }
2008                } while (true);
2009            }
2010            }
2011        }
2012    };
2013
2014    /**
2015     * Monitor for package changes and update our internal state.
2016     */
2017    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
2018        @Override
2019        public void onPackageRemoved(String packageName, int uid) {
2020            // Remove all tasks with activities in the specified package from the list of recent tasks
2021            final int eventUserId = getChangingUserId();
2022            synchronized (ActivityManagerService.this) {
2023                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2024                    TaskRecord tr = mRecentTasks.get(i);
2025                    if (tr.userId != eventUserId) continue;
2026
2027                    ComponentName cn = tr.intent.getComponent();
2028                    if (cn != null && cn.getPackageName().equals(packageName)) {
2029                        // If the package name matches, remove the task and kill the process
2030                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
2031                    }
2032                }
2033            }
2034        }
2035
2036        @Override
2037        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2038            onPackageModified(packageName);
2039            return true;
2040        }
2041
2042        @Override
2043        public void onPackageModified(String packageName) {
2044            final int eventUserId = getChangingUserId();
2045            final IPackageManager pm = AppGlobals.getPackageManager();
2046            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2047                    new ArrayList<Pair<Intent, Integer>>();
2048            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
2049            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2050            // Copy the list of recent tasks so that we don't hold onto the lock on
2051            // ActivityManagerService for long periods while checking if components exist.
2052            synchronized (ActivityManagerService.this) {
2053                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2054                    TaskRecord tr = mRecentTasks.get(i);
2055                    if (tr.userId != eventUserId) continue;
2056
2057                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2058                }
2059            }
2060            // Check the recent tasks and filter out all tasks with components that no longer exist.
2061            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2062                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2063                ComponentName cn = p.first.getComponent();
2064                if (cn != null && cn.getPackageName().equals(packageName)) {
2065                    if (componentsKnownToExist.contains(cn)) {
2066                        // If we know that the component still exists in the package, then skip
2067                        continue;
2068                    }
2069                    try {
2070                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
2071                        if (info != null) {
2072                            componentsKnownToExist.add(cn);
2073                        } else {
2074                            tasksToRemove.add(p.second);
2075                        }
2076                    } catch (RemoteException e) {
2077                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
2078                    }
2079                }
2080            }
2081            // Prune all the tasks with removed components from the list of recent tasks
2082            synchronized (ActivityManagerService.this) {
2083                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2084                    // Remove the task but don't kill the process (since other components in that
2085                    // package may still be running and in the background)
2086                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2087                }
2088            }
2089        }
2090
2091        @Override
2092        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2093            // Force stop the specified packages
2094            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
2095            if (packages != null) {
2096                for (String pkg : packages) {
2097                    synchronized (ActivityManagerService.this) {
2098                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
2099                                userId, "finished booting")) {
2100                            return true;
2101                        }
2102                    }
2103                }
2104            }
2105            return false;
2106        }
2107    };
2108
2109    public void setSystemProcess() {
2110        try {
2111            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2112            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2113            ServiceManager.addService("meminfo", new MemBinder(this));
2114            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2115            ServiceManager.addService("dbinfo", new DbBinder(this));
2116            if (MONITOR_CPU_USAGE) {
2117                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2118            }
2119            ServiceManager.addService("permission", new PermissionController(this));
2120
2121            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2122                    "android", STOCK_PM_FLAGS);
2123            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2124
2125            synchronized (this) {
2126                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2127                app.persistent = true;
2128                app.pid = MY_PID;
2129                app.maxAdj = ProcessList.SYSTEM_ADJ;
2130                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2131                mProcessNames.put(app.processName, app.uid, app);
2132                synchronized (mPidsSelfLocked) {
2133                    mPidsSelfLocked.put(app.pid, app);
2134                }
2135                updateLruProcessLocked(app, false, null);
2136                updateOomAdjLocked();
2137            }
2138        } catch (PackageManager.NameNotFoundException e) {
2139            throw new RuntimeException(
2140                    "Unable to find android system package", e);
2141        }
2142    }
2143
2144    public void setWindowManager(WindowManagerService wm) {
2145        mWindowManager = wm;
2146        mStackSupervisor.setWindowManager(wm);
2147    }
2148
2149    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2150        mUsageStatsService = usageStatsManager;
2151    }
2152
2153    public void startObservingNativeCrashes() {
2154        final NativeCrashListener ncl = new NativeCrashListener(this);
2155        ncl.start();
2156    }
2157
2158    public IAppOpsService getAppOpsService() {
2159        return mAppOpsService;
2160    }
2161
2162    static class MemBinder extends Binder {
2163        ActivityManagerService mActivityManagerService;
2164        MemBinder(ActivityManagerService activityManagerService) {
2165            mActivityManagerService = activityManagerService;
2166        }
2167
2168        @Override
2169        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2170            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2171                    != PackageManager.PERMISSION_GRANTED) {
2172                pw.println("Permission Denial: can't dump meminfo from from pid="
2173                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2174                        + " without permission " + android.Manifest.permission.DUMP);
2175                return;
2176            }
2177
2178            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2179        }
2180    }
2181
2182    static class GraphicsBinder extends Binder {
2183        ActivityManagerService mActivityManagerService;
2184        GraphicsBinder(ActivityManagerService activityManagerService) {
2185            mActivityManagerService = activityManagerService;
2186        }
2187
2188        @Override
2189        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2190            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2191                    != PackageManager.PERMISSION_GRANTED) {
2192                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2193                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2194                        + " without permission " + android.Manifest.permission.DUMP);
2195                return;
2196            }
2197
2198            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2199        }
2200    }
2201
2202    static class DbBinder extends Binder {
2203        ActivityManagerService mActivityManagerService;
2204        DbBinder(ActivityManagerService activityManagerService) {
2205            mActivityManagerService = activityManagerService;
2206        }
2207
2208        @Override
2209        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2210            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2211                    != PackageManager.PERMISSION_GRANTED) {
2212                pw.println("Permission Denial: can't dump dbinfo from from pid="
2213                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2214                        + " without permission " + android.Manifest.permission.DUMP);
2215                return;
2216            }
2217
2218            mActivityManagerService.dumpDbInfo(fd, pw, args);
2219        }
2220    }
2221
2222    static class CpuBinder extends Binder {
2223        ActivityManagerService mActivityManagerService;
2224        CpuBinder(ActivityManagerService activityManagerService) {
2225            mActivityManagerService = activityManagerService;
2226        }
2227
2228        @Override
2229        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2230            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2231                    != PackageManager.PERMISSION_GRANTED) {
2232                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2233                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2234                        + " without permission " + android.Manifest.permission.DUMP);
2235                return;
2236            }
2237
2238            synchronized (mActivityManagerService.mProcessCpuTracker) {
2239                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2240                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2241                        SystemClock.uptimeMillis()));
2242            }
2243        }
2244    }
2245
2246    public static final class Lifecycle extends SystemService {
2247        private final ActivityManagerService mService;
2248
2249        public Lifecycle(Context context) {
2250            super(context);
2251            mService = new ActivityManagerService(context);
2252        }
2253
2254        @Override
2255        public void onStart() {
2256            mService.start();
2257        }
2258
2259        public ActivityManagerService getService() {
2260            return mService;
2261        }
2262    }
2263
2264    // Note: This method is invoked on the main thread but may need to attach various
2265    // handlers to other threads.  So take care to be explicit about the looper.
2266    public ActivityManagerService(Context systemContext) {
2267        mContext = systemContext;
2268        mFactoryTest = FactoryTest.getMode();
2269        mSystemThread = ActivityThread.currentActivityThread();
2270
2271        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2272
2273        mHandlerThread = new ServiceThread(TAG,
2274                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2275        mHandlerThread.start();
2276        mHandler = new MainHandler(mHandlerThread.getLooper());
2277
2278        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2279                "foreground", BROADCAST_FG_TIMEOUT, false);
2280        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2281                "background", BROADCAST_BG_TIMEOUT, true);
2282        mBroadcastQueues[0] = mFgBroadcastQueue;
2283        mBroadcastQueues[1] = mBgBroadcastQueue;
2284
2285        mServices = new ActiveServices(this);
2286        mProviderMap = new ProviderMap(this);
2287
2288        // TODO: Move creation of battery stats service outside of activity manager service.
2289        File dataDir = Environment.getDataDirectory();
2290        File systemDir = new File(dataDir, "system");
2291        systemDir.mkdirs();
2292        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2293        mBatteryStatsService.getActiveStatistics().readLocked();
2294        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2295        mOnBattery = DEBUG_POWER ? true
2296                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2297        mBatteryStatsService.getActiveStatistics().setCallback(this);
2298
2299        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2300
2301        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2302
2303        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2304
2305        // User 0 is the first and only user that runs at boot.
2306        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2307        mUserLru.add(Integer.valueOf(0));
2308        updateStartedUserArrayLocked();
2309
2310        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2311            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2312
2313        mConfiguration.setToDefaults();
2314        mConfiguration.setLocale(Locale.getDefault());
2315
2316        mConfigurationSeq = mConfiguration.seq = 1;
2317        mProcessCpuTracker.init();
2318
2319        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2320        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2321        mStackSupervisor = new ActivityStackSupervisor(this);
2322        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2323
2324        mProcessCpuThread = new Thread("CpuTracker") {
2325            @Override
2326            public void run() {
2327                while (true) {
2328                    try {
2329                        try {
2330                            synchronized(this) {
2331                                final long now = SystemClock.uptimeMillis();
2332                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2333                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2334                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2335                                //        + ", write delay=" + nextWriteDelay);
2336                                if (nextWriteDelay < nextCpuDelay) {
2337                                    nextCpuDelay = nextWriteDelay;
2338                                }
2339                                if (nextCpuDelay > 0) {
2340                                    mProcessCpuMutexFree.set(true);
2341                                    this.wait(nextCpuDelay);
2342                                }
2343                            }
2344                        } catch (InterruptedException e) {
2345                        }
2346                        updateCpuStatsNow();
2347                    } catch (Exception e) {
2348                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2349                    }
2350                }
2351            }
2352        };
2353
2354        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2355
2356        Watchdog.getInstance().addMonitor(this);
2357        Watchdog.getInstance().addThread(mHandler);
2358    }
2359
2360    public void setSystemServiceManager(SystemServiceManager mgr) {
2361        mSystemServiceManager = mgr;
2362    }
2363
2364    public void setInstaller(Installer installer) {
2365        mInstaller = installer;
2366    }
2367
2368    private void start() {
2369        Process.removeAllProcessGroups();
2370        mProcessCpuThread.start();
2371
2372        mBatteryStatsService.publish(mContext);
2373        mAppOpsService.publish(mContext);
2374        Slog.d("AppOps", "AppOpsService published");
2375        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2376    }
2377
2378    public void initPowerManagement() {
2379        mStackSupervisor.initPowerManagement();
2380        mBatteryStatsService.initPowerManagement();
2381    }
2382
2383    @Override
2384    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2385            throws RemoteException {
2386        if (code == SYSPROPS_TRANSACTION) {
2387            // We need to tell all apps about the system property change.
2388            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2389            synchronized(this) {
2390                final int NP = mProcessNames.getMap().size();
2391                for (int ip=0; ip<NP; ip++) {
2392                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2393                    final int NA = apps.size();
2394                    for (int ia=0; ia<NA; ia++) {
2395                        ProcessRecord app = apps.valueAt(ia);
2396                        if (app.thread != null) {
2397                            procs.add(app.thread.asBinder());
2398                        }
2399                    }
2400                }
2401            }
2402
2403            int N = procs.size();
2404            for (int i=0; i<N; i++) {
2405                Parcel data2 = Parcel.obtain();
2406                try {
2407                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2408                } catch (RemoteException e) {
2409                }
2410                data2.recycle();
2411            }
2412        }
2413        try {
2414            return super.onTransact(code, data, reply, flags);
2415        } catch (RuntimeException e) {
2416            // The activity manager only throws security exceptions, so let's
2417            // log all others.
2418            if (!(e instanceof SecurityException)) {
2419                Slog.wtf(TAG, "Activity Manager Crash", e);
2420            }
2421            throw e;
2422        }
2423    }
2424
2425    void updateCpuStats() {
2426        final long now = SystemClock.uptimeMillis();
2427        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2428            return;
2429        }
2430        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2431            synchronized (mProcessCpuThread) {
2432                mProcessCpuThread.notify();
2433            }
2434        }
2435    }
2436
2437    void updateCpuStatsNow() {
2438        synchronized (mProcessCpuTracker) {
2439            mProcessCpuMutexFree.set(false);
2440            final long now = SystemClock.uptimeMillis();
2441            boolean haveNewCpuStats = false;
2442
2443            if (MONITOR_CPU_USAGE &&
2444                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2445                mLastCpuTime.set(now);
2446                haveNewCpuStats = true;
2447                mProcessCpuTracker.update();
2448                //Slog.i(TAG, mProcessCpu.printCurrentState());
2449                //Slog.i(TAG, "Total CPU usage: "
2450                //        + mProcessCpu.getTotalCpuPercent() + "%");
2451
2452                // Slog the cpu usage if the property is set.
2453                if ("true".equals(SystemProperties.get("events.cpu"))) {
2454                    int user = mProcessCpuTracker.getLastUserTime();
2455                    int system = mProcessCpuTracker.getLastSystemTime();
2456                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2457                    int irq = mProcessCpuTracker.getLastIrqTime();
2458                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2459                    int idle = mProcessCpuTracker.getLastIdleTime();
2460
2461                    int total = user + system + iowait + irq + softIrq + idle;
2462                    if (total == 0) total = 1;
2463
2464                    EventLog.writeEvent(EventLogTags.CPU,
2465                            ((user+system+iowait+irq+softIrq) * 100) / total,
2466                            (user * 100) / total,
2467                            (system * 100) / total,
2468                            (iowait * 100) / total,
2469                            (irq * 100) / total,
2470                            (softIrq * 100) / total);
2471                }
2472            }
2473
2474            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2475            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2476            synchronized(bstats) {
2477                synchronized(mPidsSelfLocked) {
2478                    if (haveNewCpuStats) {
2479                        if (mOnBattery) {
2480                            int perc = bstats.startAddingCpuLocked();
2481                            int totalUTime = 0;
2482                            int totalSTime = 0;
2483                            final int N = mProcessCpuTracker.countStats();
2484                            for (int i=0; i<N; i++) {
2485                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2486                                if (!st.working) {
2487                                    continue;
2488                                }
2489                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2490                                int otherUTime = (st.rel_utime*perc)/100;
2491                                int otherSTime = (st.rel_stime*perc)/100;
2492                                totalUTime += otherUTime;
2493                                totalSTime += otherSTime;
2494                                if (pr != null) {
2495                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2496                                    if (ps == null || !ps.isActive()) {
2497                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2498                                                pr.info.uid, pr.processName);
2499                                    }
2500                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2501                                            st.rel_stime-otherSTime);
2502                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2503                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2504                                } else {
2505                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2506                                    if (ps == null || !ps.isActive()) {
2507                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2508                                                bstats.mapUid(st.uid), st.name);
2509                                    }
2510                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2511                                            st.rel_stime-otherSTime);
2512                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2513                                }
2514                            }
2515                            bstats.finishAddingCpuLocked(perc, totalUTime,
2516                                    totalSTime, cpuSpeedTimes);
2517                        }
2518                    }
2519                }
2520
2521                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2522                    mLastWriteTime = now;
2523                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2524                }
2525            }
2526        }
2527    }
2528
2529    @Override
2530    public void batteryNeedsCpuUpdate() {
2531        updateCpuStatsNow();
2532    }
2533
2534    @Override
2535    public void batteryPowerChanged(boolean onBattery) {
2536        // When plugging in, update the CPU stats first before changing
2537        // the plug state.
2538        updateCpuStatsNow();
2539        synchronized (this) {
2540            synchronized(mPidsSelfLocked) {
2541                mOnBattery = DEBUG_POWER ? true : onBattery;
2542            }
2543        }
2544    }
2545
2546    /**
2547     * Initialize the application bind args. These are passed to each
2548     * process when the bindApplication() IPC is sent to the process. They're
2549     * lazily setup to make sure the services are running when they're asked for.
2550     */
2551    private HashMap<String, IBinder> getCommonServicesLocked() {
2552        if (mAppBindArgs == null) {
2553            mAppBindArgs = new HashMap<String, IBinder>();
2554
2555            // Setup the application init args
2556            mAppBindArgs.put("package", ServiceManager.getService("package"));
2557            mAppBindArgs.put("window", ServiceManager.getService("window"));
2558            mAppBindArgs.put(Context.ALARM_SERVICE,
2559                    ServiceManager.getService(Context.ALARM_SERVICE));
2560        }
2561        return mAppBindArgs;
2562    }
2563
2564    final void setFocusedActivityLocked(ActivityRecord r) {
2565        if (mFocusedActivity != r) {
2566            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2567            mFocusedActivity = r;
2568            if (r.task != null && r.task.voiceInteractor != null) {
2569                startRunningVoiceLocked();
2570            } else {
2571                finishRunningVoiceLocked();
2572            }
2573            mStackSupervisor.setFocusedStack(r);
2574            if (r != null) {
2575                mWindowManager.setFocusedApp(r.appToken, true);
2576            }
2577            applyUpdateLockStateLocked(r);
2578        }
2579    }
2580
2581    final void clearFocusedActivity(ActivityRecord r) {
2582        if (mFocusedActivity == r) {
2583            mFocusedActivity = null;
2584        }
2585    }
2586
2587    @Override
2588    public void setFocusedStack(int stackId) {
2589        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2590        synchronized (ActivityManagerService.this) {
2591            ActivityStack stack = mStackSupervisor.getStack(stackId);
2592            if (stack != null) {
2593                ActivityRecord r = stack.topRunningActivityLocked(null);
2594                if (r != null) {
2595                    setFocusedActivityLocked(r);
2596                }
2597            }
2598        }
2599    }
2600
2601    @Override
2602    public void notifyActivityDrawn(IBinder token) {
2603        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2604        synchronized (this) {
2605            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2606            if (r != null) {
2607                r.task.stack.notifyActivityDrawnLocked(r);
2608            }
2609        }
2610    }
2611
2612    final void applyUpdateLockStateLocked(ActivityRecord r) {
2613        // Modifications to the UpdateLock state are done on our handler, outside
2614        // the activity manager's locks.  The new state is determined based on the
2615        // state *now* of the relevant activity record.  The object is passed to
2616        // the handler solely for logging detail, not to be consulted/modified.
2617        final boolean nextState = r != null && r.immersive;
2618        mHandler.sendMessage(
2619                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2620    }
2621
2622    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2623        Message msg = Message.obtain();
2624        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2625        msg.obj = r.task.askedCompatMode ? null : r;
2626        mHandler.sendMessage(msg);
2627    }
2628
2629    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2630            String what, Object obj, ProcessRecord srcApp) {
2631        app.lastActivityTime = now;
2632
2633        if (app.activities.size() > 0) {
2634            // Don't want to touch dependent processes that are hosting activities.
2635            return index;
2636        }
2637
2638        int lrui = mLruProcesses.lastIndexOf(app);
2639        if (lrui < 0) {
2640            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2641                    + what + " " + obj + " from " + srcApp);
2642            return index;
2643        }
2644
2645        if (lrui >= index) {
2646            // Don't want to cause this to move dependent processes *back* in the
2647            // list as if they were less frequently used.
2648            return index;
2649        }
2650
2651        if (lrui >= mLruProcessActivityStart) {
2652            // Don't want to touch dependent processes that are hosting activities.
2653            return index;
2654        }
2655
2656        mLruProcesses.remove(lrui);
2657        if (index > 0) {
2658            index--;
2659        }
2660        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2661                + " in LRU list: " + app);
2662        mLruProcesses.add(index, app);
2663        return index;
2664    }
2665
2666    final void removeLruProcessLocked(ProcessRecord app) {
2667        int lrui = mLruProcesses.lastIndexOf(app);
2668        if (lrui >= 0) {
2669            if (!app.killed) {
2670                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2671                Process.killProcessQuiet(app.pid);
2672                Process.killProcessGroup(app.info.uid, app.pid);
2673            }
2674            if (lrui <= mLruProcessActivityStart) {
2675                mLruProcessActivityStart--;
2676            }
2677            if (lrui <= mLruProcessServiceStart) {
2678                mLruProcessServiceStart--;
2679            }
2680            mLruProcesses.remove(lrui);
2681        }
2682    }
2683
2684    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2685            ProcessRecord client) {
2686        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2687                || app.treatLikeActivity;
2688        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2689        if (!activityChange && hasActivity) {
2690            // The process has activities, so we are only allowing activity-based adjustments
2691            // to move it.  It should be kept in the front of the list with other
2692            // processes that have activities, and we don't want those to change their
2693            // order except due to activity operations.
2694            return;
2695        }
2696
2697        mLruSeq++;
2698        final long now = SystemClock.uptimeMillis();
2699        app.lastActivityTime = now;
2700
2701        // First a quick reject: if the app is already at the position we will
2702        // put it, then there is nothing to do.
2703        if (hasActivity) {
2704            final int N = mLruProcesses.size();
2705            if (N > 0 && mLruProcesses.get(N-1) == app) {
2706                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2707                return;
2708            }
2709        } else {
2710            if (mLruProcessServiceStart > 0
2711                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2712                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2713                return;
2714            }
2715        }
2716
2717        int lrui = mLruProcesses.lastIndexOf(app);
2718
2719        if (app.persistent && lrui >= 0) {
2720            // We don't care about the position of persistent processes, as long as
2721            // they are in the list.
2722            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2723            return;
2724        }
2725
2726        /* In progress: compute new position first, so we can avoid doing work
2727           if the process is not actually going to move.  Not yet working.
2728        int addIndex;
2729        int nextIndex;
2730        boolean inActivity = false, inService = false;
2731        if (hasActivity) {
2732            // Process has activities, put it at the very tipsy-top.
2733            addIndex = mLruProcesses.size();
2734            nextIndex = mLruProcessServiceStart;
2735            inActivity = true;
2736        } else if (hasService) {
2737            // Process has services, put it at the top of the service list.
2738            addIndex = mLruProcessActivityStart;
2739            nextIndex = mLruProcessServiceStart;
2740            inActivity = true;
2741            inService = true;
2742        } else  {
2743            // Process not otherwise of interest, it goes to the top of the non-service area.
2744            addIndex = mLruProcessServiceStart;
2745            if (client != null) {
2746                int clientIndex = mLruProcesses.lastIndexOf(client);
2747                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2748                        + app);
2749                if (clientIndex >= 0 && addIndex > clientIndex) {
2750                    addIndex = clientIndex;
2751                }
2752            }
2753            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2754        }
2755
2756        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2757                + mLruProcessActivityStart + "): " + app);
2758        */
2759
2760        if (lrui >= 0) {
2761            if (lrui < mLruProcessActivityStart) {
2762                mLruProcessActivityStart--;
2763            }
2764            if (lrui < mLruProcessServiceStart) {
2765                mLruProcessServiceStart--;
2766            }
2767            /*
2768            if (addIndex > lrui) {
2769                addIndex--;
2770            }
2771            if (nextIndex > lrui) {
2772                nextIndex--;
2773            }
2774            */
2775            mLruProcesses.remove(lrui);
2776        }
2777
2778        /*
2779        mLruProcesses.add(addIndex, app);
2780        if (inActivity) {
2781            mLruProcessActivityStart++;
2782        }
2783        if (inService) {
2784            mLruProcessActivityStart++;
2785        }
2786        */
2787
2788        int nextIndex;
2789        if (hasActivity) {
2790            final int N = mLruProcesses.size();
2791            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2792                // Process doesn't have activities, but has clients with
2793                // activities...  move it up, but one below the top (the top
2794                // should always have a real activity).
2795                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2796                mLruProcesses.add(N-1, app);
2797                // To keep it from spamming the LRU list (by making a bunch of clients),
2798                // we will push down any other entries owned by the app.
2799                final int uid = app.info.uid;
2800                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2801                    ProcessRecord subProc = mLruProcesses.get(i);
2802                    if (subProc.info.uid == uid) {
2803                        // We want to push this one down the list.  If the process after
2804                        // it is for the same uid, however, don't do so, because we don't
2805                        // want them internally to be re-ordered.
2806                        if (mLruProcesses.get(i-1).info.uid != uid) {
2807                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2808                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2809                            ProcessRecord tmp = mLruProcesses.get(i);
2810                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2811                            mLruProcesses.set(i-1, tmp);
2812                            i--;
2813                        }
2814                    } else {
2815                        // A gap, we can stop here.
2816                        break;
2817                    }
2818                }
2819            } else {
2820                // Process has activities, put it at the very tipsy-top.
2821                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2822                mLruProcesses.add(app);
2823            }
2824            nextIndex = mLruProcessServiceStart;
2825        } else if (hasService) {
2826            // Process has services, put it at the top of the service list.
2827            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2828            mLruProcesses.add(mLruProcessActivityStart, app);
2829            nextIndex = mLruProcessServiceStart;
2830            mLruProcessActivityStart++;
2831        } else  {
2832            // Process not otherwise of interest, it goes to the top of the non-service area.
2833            int index = mLruProcessServiceStart;
2834            if (client != null) {
2835                // If there is a client, don't allow the process to be moved up higher
2836                // in the list than that client.
2837                int clientIndex = mLruProcesses.lastIndexOf(client);
2838                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2839                        + " when updating " + app);
2840                if (clientIndex <= lrui) {
2841                    // Don't allow the client index restriction to push it down farther in the
2842                    // list than it already is.
2843                    clientIndex = lrui;
2844                }
2845                if (clientIndex >= 0 && index > clientIndex) {
2846                    index = clientIndex;
2847                }
2848            }
2849            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2850            mLruProcesses.add(index, app);
2851            nextIndex = index-1;
2852            mLruProcessActivityStart++;
2853            mLruProcessServiceStart++;
2854        }
2855
2856        // If the app is currently using a content provider or service,
2857        // bump those processes as well.
2858        for (int j=app.connections.size()-1; j>=0; j--) {
2859            ConnectionRecord cr = app.connections.valueAt(j);
2860            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2861                    && cr.binding.service.app != null
2862                    && cr.binding.service.app.lruSeq != mLruSeq
2863                    && !cr.binding.service.app.persistent) {
2864                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2865                        "service connection", cr, app);
2866            }
2867        }
2868        for (int j=app.conProviders.size()-1; j>=0; j--) {
2869            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2870            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2871                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2872                        "provider reference", cpr, app);
2873            }
2874        }
2875    }
2876
2877    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2878        if (uid == Process.SYSTEM_UID) {
2879            // The system gets to run in any process.  If there are multiple
2880            // processes with the same uid, just pick the first (this
2881            // should never happen).
2882            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2883            if (procs == null) return null;
2884            final int N = procs.size();
2885            for (int i = 0; i < N; i++) {
2886                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2887            }
2888        }
2889        ProcessRecord proc = mProcessNames.get(processName, uid);
2890        if (false && proc != null && !keepIfLarge
2891                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2892                && proc.lastCachedPss >= 4000) {
2893            // Turn this condition on to cause killing to happen regularly, for testing.
2894            if (proc.baseProcessTracker != null) {
2895                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2896            }
2897            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2898        } else if (proc != null && !keepIfLarge
2899                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2900                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2901            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2902            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2903                if (proc.baseProcessTracker != null) {
2904                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2905                }
2906                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2907            }
2908        }
2909        return proc;
2910    }
2911
2912    void ensurePackageDexOpt(String packageName) {
2913        IPackageManager pm = AppGlobals.getPackageManager();
2914        try {
2915            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2916                mDidDexOpt = true;
2917            }
2918        } catch (RemoteException e) {
2919        }
2920    }
2921
2922    boolean isNextTransitionForward() {
2923        int transit = mWindowManager.getPendingAppTransition();
2924        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2925                || transit == AppTransition.TRANSIT_TASK_OPEN
2926                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2927    }
2928
2929    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2930            String processName, String abiOverride, int uid, Runnable crashHandler) {
2931        synchronized(this) {
2932            ApplicationInfo info = new ApplicationInfo();
2933            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2934            // For isolated processes, the former contains the parent's uid and the latter the
2935            // actual uid of the isolated process.
2936            // In the special case introduced by this method (which is, starting an isolated
2937            // process directly from the SystemServer without an actual parent app process) the
2938            // closest thing to a parent's uid is SYSTEM_UID.
2939            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2940            // the |isolated| logic in the ProcessRecord constructor.
2941            info.uid = Process.SYSTEM_UID;
2942            info.processName = processName;
2943            info.className = entryPoint;
2944            info.packageName = "android";
2945            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2946                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2947                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2948                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2949                    crashHandler);
2950            return proc != null ? proc.pid : 0;
2951        }
2952    }
2953
2954    final ProcessRecord startProcessLocked(String processName,
2955            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2956            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2957            boolean isolated, boolean keepIfLarge) {
2958        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2959                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2960                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2961                null /* crashHandler */);
2962    }
2963
2964    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2965            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2966            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2967            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2968        long startTime = SystemClock.elapsedRealtime();
2969        ProcessRecord app;
2970        if (!isolated) {
2971            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2972            checkTime(startTime, "startProcess: after getProcessRecord");
2973        } else {
2974            // If this is an isolated process, it can't re-use an existing process.
2975            app = null;
2976        }
2977        // We don't have to do anything more if:
2978        // (1) There is an existing application record; and
2979        // (2) The caller doesn't think it is dead, OR there is no thread
2980        //     object attached to it so we know it couldn't have crashed; and
2981        // (3) There is a pid assigned to it, so it is either starting or
2982        //     already running.
2983        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2984                + " app=" + app + " knownToBeDead=" + knownToBeDead
2985                + " thread=" + (app != null ? app.thread : null)
2986                + " pid=" + (app != null ? app.pid : -1));
2987        if (app != null && app.pid > 0) {
2988            if (!knownToBeDead || app.thread == null) {
2989                // We already have the app running, or are waiting for it to
2990                // come up (we have a pid but not yet its thread), so keep it.
2991                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2992                // If this is a new package in the process, add the package to the list
2993                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2994                checkTime(startTime, "startProcess: done, added package to proc");
2995                return app;
2996            }
2997
2998            // An application record is attached to a previous process,
2999            // clean it up now.
3000            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
3001            checkTime(startTime, "startProcess: bad proc running, killing");
3002            Process.killProcessGroup(app.info.uid, app.pid);
3003            handleAppDiedLocked(app, true, true);
3004            checkTime(startTime, "startProcess: done killing old proc");
3005        }
3006
3007        String hostingNameStr = hostingName != null
3008                ? hostingName.flattenToShortString() : null;
3009
3010        if (!isolated) {
3011            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
3012                // If we are in the background, then check to see if this process
3013                // is bad.  If so, we will just silently fail.
3014                if (mBadProcesses.get(info.processName, info.uid) != null) {
3015                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3016                            + "/" + info.processName);
3017                    return null;
3018                }
3019            } else {
3020                // When the user is explicitly starting a process, then clear its
3021                // crash count so that we won't make it bad until they see at
3022                // least one crash dialog again, and make the process good again
3023                // if it had been bad.
3024                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3025                        + "/" + info.processName);
3026                mProcessCrashTimes.remove(info.processName, info.uid);
3027                if (mBadProcesses.get(info.processName, info.uid) != null) {
3028                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3029                            UserHandle.getUserId(info.uid), info.uid,
3030                            info.processName);
3031                    mBadProcesses.remove(info.processName, info.uid);
3032                    if (app != null) {
3033                        app.bad = false;
3034                    }
3035                }
3036            }
3037        }
3038
3039        if (app == null) {
3040            checkTime(startTime, "startProcess: creating new process record");
3041            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3042            app.crashHandler = crashHandler;
3043            if (app == null) {
3044                Slog.w(TAG, "Failed making new process record for "
3045                        + processName + "/" + info.uid + " isolated=" + isolated);
3046                return null;
3047            }
3048            mProcessNames.put(processName, app.uid, app);
3049            if (isolated) {
3050                mIsolatedProcesses.put(app.uid, app);
3051            }
3052            checkTime(startTime, "startProcess: done creating new process record");
3053        } else {
3054            // If this is a new package in the process, add the package to the list
3055            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3056            checkTime(startTime, "startProcess: added package to existing proc");
3057        }
3058
3059        // If the system is not ready yet, then hold off on starting this
3060        // process until it is.
3061        if (!mProcessesReady
3062                && !isAllowedWhileBooting(info)
3063                && !allowWhileBooting) {
3064            if (!mProcessesOnHold.contains(app)) {
3065                mProcessesOnHold.add(app);
3066            }
3067            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3068            checkTime(startTime, "startProcess: returning with proc on hold");
3069            return app;
3070        }
3071
3072        checkTime(startTime, "startProcess: stepping in to startProcess");
3073        startProcessLocked(
3074                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3075        checkTime(startTime, "startProcess: done starting proc!");
3076        return (app.pid != 0) ? app : null;
3077    }
3078
3079    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3080        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3081    }
3082
3083    private final void startProcessLocked(ProcessRecord app,
3084            String hostingType, String hostingNameStr) {
3085        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3086                null /* entryPoint */, null /* entryPointArgs */);
3087    }
3088
3089    private final void startProcessLocked(ProcessRecord app, String hostingType,
3090            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3091        long startTime = SystemClock.elapsedRealtime();
3092        if (app.pid > 0 && app.pid != MY_PID) {
3093            checkTime(startTime, "startProcess: removing from pids map");
3094            synchronized (mPidsSelfLocked) {
3095                mPidsSelfLocked.remove(app.pid);
3096                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3097            }
3098            checkTime(startTime, "startProcess: done removing from pids map");
3099            app.setPid(0);
3100        }
3101
3102        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3103                "startProcessLocked removing on hold: " + app);
3104        mProcessesOnHold.remove(app);
3105
3106        checkTime(startTime, "startProcess: starting to update cpu stats");
3107        updateCpuStats();
3108        checkTime(startTime, "startProcess: done updating cpu stats");
3109
3110        try {
3111            int uid = app.uid;
3112
3113            int[] gids = null;
3114            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3115            if (!app.isolated) {
3116                int[] permGids = null;
3117                try {
3118                    checkTime(startTime, "startProcess: getting gids from package manager");
3119                    final PackageManager pm = mContext.getPackageManager();
3120                    permGids = pm.getPackageGids(app.info.packageName);
3121
3122                    if (Environment.isExternalStorageEmulated()) {
3123                        checkTime(startTime, "startProcess: checking external storage perm");
3124                        if (pm.checkPermission(
3125                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3126                                app.info.packageName) == PERMISSION_GRANTED) {
3127                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3128                        } else {
3129                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3130                        }
3131                    }
3132                } catch (PackageManager.NameNotFoundException e) {
3133                    Slog.w(TAG, "Unable to retrieve gids", e);
3134                }
3135
3136                /*
3137                 * Add shared application and profile GIDs so applications can share some
3138                 * resources like shared libraries and access user-wide resources
3139                 */
3140                if (permGids == null) {
3141                    gids = new int[2];
3142                } else {
3143                    gids = new int[permGids.length + 2];
3144                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3145                }
3146                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3147                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3148            }
3149            checkTime(startTime, "startProcess: building args");
3150            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3151                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3152                        && mTopComponent != null
3153                        && app.processName.equals(mTopComponent.getPackageName())) {
3154                    uid = 0;
3155                }
3156                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3157                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3158                    uid = 0;
3159                }
3160            }
3161            int debugFlags = 0;
3162            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3163                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3164                // Also turn on CheckJNI for debuggable apps. It's quite
3165                // awkward to turn on otherwise.
3166                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3167            }
3168            // Run the app in safe mode if its manifest requests so or the
3169            // system is booted in safe mode.
3170            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3171                mSafeMode == true) {
3172                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3173            }
3174            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3175                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3176            }
3177            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3178                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3179            }
3180            if ("1".equals(SystemProperties.get("debug.assert"))) {
3181                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3182            }
3183
3184            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3185            if (requiredAbi == null) {
3186                requiredAbi = Build.SUPPORTED_ABIS[0];
3187            }
3188
3189            String instructionSet = null;
3190            if (app.info.primaryCpuAbi != null) {
3191                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3192            }
3193
3194            // Start the process.  It will either succeed and return a result containing
3195            // the PID of the new process, or else throw a RuntimeException.
3196            boolean isActivityProcess = (entryPoint == null);
3197            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3198            checkTime(startTime, "startProcess: asking zygote to start proc");
3199            Process.ProcessStartResult startResult = Process.start(entryPoint,
3200                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3201                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3202                    app.info.dataDir, entryPointArgs);
3203            checkTime(startTime, "startProcess: returned from zygote!");
3204
3205            if (app.isolated) {
3206                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3207            }
3208            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3209            checkTime(startTime, "startProcess: done updating battery stats");
3210
3211            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3212                    UserHandle.getUserId(uid), startResult.pid, uid,
3213                    app.processName, hostingType,
3214                    hostingNameStr != null ? hostingNameStr : "");
3215
3216            if (app.persistent) {
3217                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3218            }
3219
3220            checkTime(startTime, "startProcess: building log message");
3221            StringBuilder buf = mStringBuilder;
3222            buf.setLength(0);
3223            buf.append("Start proc ");
3224            buf.append(app.processName);
3225            if (!isActivityProcess) {
3226                buf.append(" [");
3227                buf.append(entryPoint);
3228                buf.append("]");
3229            }
3230            buf.append(" for ");
3231            buf.append(hostingType);
3232            if (hostingNameStr != null) {
3233                buf.append(" ");
3234                buf.append(hostingNameStr);
3235            }
3236            buf.append(": pid=");
3237            buf.append(startResult.pid);
3238            buf.append(" uid=");
3239            buf.append(uid);
3240            buf.append(" gids={");
3241            if (gids != null) {
3242                for (int gi=0; gi<gids.length; gi++) {
3243                    if (gi != 0) buf.append(", ");
3244                    buf.append(gids[gi]);
3245
3246                }
3247            }
3248            buf.append("}");
3249            if (requiredAbi != null) {
3250                buf.append(" abi=");
3251                buf.append(requiredAbi);
3252            }
3253            Slog.i(TAG, buf.toString());
3254            app.setPid(startResult.pid);
3255            app.usingWrapper = startResult.usingWrapper;
3256            app.removed = false;
3257            app.killed = false;
3258            app.killedByAm = false;
3259            checkTime(startTime, "startProcess: starting to update pids map");
3260            synchronized (mPidsSelfLocked) {
3261                this.mPidsSelfLocked.put(startResult.pid, app);
3262                if (isActivityProcess) {
3263                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3264                    msg.obj = app;
3265                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3266                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3267                }
3268            }
3269            checkTime(startTime, "startProcess: done updating pids map");
3270        } catch (RuntimeException e) {
3271            // XXX do better error recovery.
3272            app.setPid(0);
3273            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3274            if (app.isolated) {
3275                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3276            }
3277            Slog.e(TAG, "Failure starting process " + app.processName, e);
3278        }
3279    }
3280
3281    void updateUsageStats(ActivityRecord component, boolean resumed) {
3282        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3283        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3284        if (resumed) {
3285            if (mUsageStatsService != null) {
3286                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3287                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3288            }
3289            synchronized (stats) {
3290                stats.noteActivityResumedLocked(component.app.uid);
3291            }
3292        } else {
3293            if (mUsageStatsService != null) {
3294                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3295                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3296            }
3297            synchronized (stats) {
3298                stats.noteActivityPausedLocked(component.app.uid);
3299            }
3300        }
3301    }
3302
3303    Intent getHomeIntent() {
3304        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3305        intent.setComponent(mTopComponent);
3306        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3307            intent.addCategory(Intent.CATEGORY_HOME);
3308        }
3309        return intent;
3310    }
3311
3312    boolean startHomeActivityLocked(int userId) {
3313        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3314                && mTopAction == null) {
3315            // We are running in factory test mode, but unable to find
3316            // the factory test app, so just sit around displaying the
3317            // error message and don't try to start anything.
3318            return false;
3319        }
3320        Intent intent = getHomeIntent();
3321        ActivityInfo aInfo =
3322            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3323        if (aInfo != null) {
3324            intent.setComponent(new ComponentName(
3325                    aInfo.applicationInfo.packageName, aInfo.name));
3326            // Don't do this if the home app is currently being
3327            // instrumented.
3328            aInfo = new ActivityInfo(aInfo);
3329            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3330            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3331                    aInfo.applicationInfo.uid, true);
3332            if (app == null || app.instrumentationClass == null) {
3333                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3334                mStackSupervisor.startHomeActivity(intent, aInfo);
3335            }
3336        }
3337
3338        return true;
3339    }
3340
3341    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3342        ActivityInfo ai = null;
3343        ComponentName comp = intent.getComponent();
3344        try {
3345            if (comp != null) {
3346                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3347            } else {
3348                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3349                        intent,
3350                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3351                            flags, userId);
3352
3353                if (info != null) {
3354                    ai = info.activityInfo;
3355                }
3356            }
3357        } catch (RemoteException e) {
3358            // ignore
3359        }
3360
3361        return ai;
3362    }
3363
3364    /**
3365     * Starts the "new version setup screen" if appropriate.
3366     */
3367    void startSetupActivityLocked() {
3368        // Only do this once per boot.
3369        if (mCheckedForSetup) {
3370            return;
3371        }
3372
3373        // We will show this screen if the current one is a different
3374        // version than the last one shown, and we are not running in
3375        // low-level factory test mode.
3376        final ContentResolver resolver = mContext.getContentResolver();
3377        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3378                Settings.Global.getInt(resolver,
3379                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3380            mCheckedForSetup = true;
3381
3382            // See if we should be showing the platform update setup UI.
3383            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3384            List<ResolveInfo> ris = mContext.getPackageManager()
3385                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3386
3387            // We don't allow third party apps to replace this.
3388            ResolveInfo ri = null;
3389            for (int i=0; ris != null && i<ris.size(); i++) {
3390                if ((ris.get(i).activityInfo.applicationInfo.flags
3391                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3392                    ri = ris.get(i);
3393                    break;
3394                }
3395            }
3396
3397            if (ri != null) {
3398                String vers = ri.activityInfo.metaData != null
3399                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3400                        : null;
3401                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3402                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3403                            Intent.METADATA_SETUP_VERSION);
3404                }
3405                String lastVers = Settings.Secure.getString(
3406                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3407                if (vers != null && !vers.equals(lastVers)) {
3408                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3409                    intent.setComponent(new ComponentName(
3410                            ri.activityInfo.packageName, ri.activityInfo.name));
3411                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3412                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3413                            null);
3414                }
3415            }
3416        }
3417    }
3418
3419    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3420        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3421    }
3422
3423    void enforceNotIsolatedCaller(String caller) {
3424        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3425            throw new SecurityException("Isolated process not allowed to call " + caller);
3426        }
3427    }
3428
3429    void enforceShellRestriction(String restriction, int userHandle) {
3430        if (Binder.getCallingUid() == Process.SHELL_UID) {
3431            if (userHandle < 0
3432                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3433                throw new SecurityException("Shell does not have permission to access user "
3434                        + userHandle);
3435            }
3436        }
3437    }
3438
3439    @Override
3440    public int getFrontActivityScreenCompatMode() {
3441        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3442        synchronized (this) {
3443            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3444        }
3445    }
3446
3447    @Override
3448    public void setFrontActivityScreenCompatMode(int mode) {
3449        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3450                "setFrontActivityScreenCompatMode");
3451        synchronized (this) {
3452            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3453        }
3454    }
3455
3456    @Override
3457    public int getPackageScreenCompatMode(String packageName) {
3458        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3459        synchronized (this) {
3460            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3461        }
3462    }
3463
3464    @Override
3465    public void setPackageScreenCompatMode(String packageName, int mode) {
3466        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3467                "setPackageScreenCompatMode");
3468        synchronized (this) {
3469            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3470        }
3471    }
3472
3473    @Override
3474    public boolean getPackageAskScreenCompat(String packageName) {
3475        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3476        synchronized (this) {
3477            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3478        }
3479    }
3480
3481    @Override
3482    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3483        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3484                "setPackageAskScreenCompat");
3485        synchronized (this) {
3486            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3487        }
3488    }
3489
3490    private void dispatchProcessesChanged() {
3491        int N;
3492        synchronized (this) {
3493            N = mPendingProcessChanges.size();
3494            if (mActiveProcessChanges.length < N) {
3495                mActiveProcessChanges = new ProcessChangeItem[N];
3496            }
3497            mPendingProcessChanges.toArray(mActiveProcessChanges);
3498            mAvailProcessChanges.addAll(mPendingProcessChanges);
3499            mPendingProcessChanges.clear();
3500            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3501        }
3502
3503        int i = mProcessObservers.beginBroadcast();
3504        while (i > 0) {
3505            i--;
3506            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3507            if (observer != null) {
3508                try {
3509                    for (int j=0; j<N; j++) {
3510                        ProcessChangeItem item = mActiveProcessChanges[j];
3511                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3512                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3513                                    + item.pid + " uid=" + item.uid + ": "
3514                                    + item.foregroundActivities);
3515                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3516                                    item.foregroundActivities);
3517                        }
3518                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3519                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3520                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3521                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3522                        }
3523                    }
3524                } catch (RemoteException e) {
3525                }
3526            }
3527        }
3528        mProcessObservers.finishBroadcast();
3529    }
3530
3531    private void dispatchProcessDied(int pid, int uid) {
3532        int i = mProcessObservers.beginBroadcast();
3533        while (i > 0) {
3534            i--;
3535            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3536            if (observer != null) {
3537                try {
3538                    observer.onProcessDied(pid, uid);
3539                } catch (RemoteException e) {
3540                }
3541            }
3542        }
3543        mProcessObservers.finishBroadcast();
3544    }
3545
3546    @Override
3547    public final int startActivity(IApplicationThread caller, String callingPackage,
3548            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3549            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3550        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3551            resultWho, requestCode, startFlags, profilerInfo, options,
3552            UserHandle.getCallingUserId());
3553    }
3554
3555    @Override
3556    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3557            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3558            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3559        enforceNotIsolatedCaller("startActivity");
3560        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3561                false, ALLOW_FULL_ONLY, "startActivity", null);
3562        // TODO: Switch to user app stacks here.
3563        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3564                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3565                profilerInfo, null, null, options, userId, null, null);
3566    }
3567
3568    @Override
3569    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3570            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3571            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3572
3573        // This is very dangerous -- it allows you to perform a start activity (including
3574        // permission grants) as any app that may launch one of your own activities.  So
3575        // we will only allow this to be done from activities that are part of the core framework,
3576        // and then only when they are running as the system.
3577        final ActivityRecord sourceRecord;
3578        final int targetUid;
3579        final String targetPackage;
3580        synchronized (this) {
3581            if (resultTo == null) {
3582                throw new SecurityException("Must be called from an activity");
3583            }
3584            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3585            if (sourceRecord == null) {
3586                throw new SecurityException("Called with bad activity token: " + resultTo);
3587            }
3588            if (!sourceRecord.info.packageName.equals("android")) {
3589                throw new SecurityException(
3590                        "Must be called from an activity that is declared in the android package");
3591            }
3592            if (sourceRecord.app == null) {
3593                throw new SecurityException("Called without a process attached to activity");
3594            }
3595            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3596                // This is still okay, as long as this activity is running under the
3597                // uid of the original calling activity.
3598                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3599                    throw new SecurityException(
3600                            "Calling activity in uid " + sourceRecord.app.uid
3601                                    + " must be system uid or original calling uid "
3602                                    + sourceRecord.launchedFromUid);
3603                }
3604            }
3605            targetUid = sourceRecord.launchedFromUid;
3606            targetPackage = sourceRecord.launchedFromPackage;
3607        }
3608
3609        if (userId == UserHandle.USER_NULL) {
3610            userId = UserHandle.getUserId(sourceRecord.app.uid);
3611        }
3612
3613        // TODO: Switch to user app stacks here.
3614        try {
3615            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3616                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3617                    null, null, options, userId, null, null);
3618            return ret;
3619        } catch (SecurityException e) {
3620            // XXX need to figure out how to propagate to original app.
3621            // A SecurityException here is generally actually a fault of the original
3622            // calling activity (such as a fairly granting permissions), so propagate it
3623            // back to them.
3624            /*
3625            StringBuilder msg = new StringBuilder();
3626            msg.append("While launching");
3627            msg.append(intent.toString());
3628            msg.append(": ");
3629            msg.append(e.getMessage());
3630            */
3631            throw e;
3632        }
3633    }
3634
3635    @Override
3636    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3637            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3638            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3639        enforceNotIsolatedCaller("startActivityAndWait");
3640        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3641                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3642        WaitResult res = new WaitResult();
3643        // TODO: Switch to user app stacks here.
3644        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3645                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3646                options, userId, null, null);
3647        return res;
3648    }
3649
3650    @Override
3651    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3652            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3653            int startFlags, Configuration config, Bundle options, int userId) {
3654        enforceNotIsolatedCaller("startActivityWithConfig");
3655        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3656                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3657        // TODO: Switch to user app stacks here.
3658        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3659                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3660                null, null, config, options, userId, null, null);
3661        return ret;
3662    }
3663
3664    @Override
3665    public int startActivityIntentSender(IApplicationThread caller,
3666            IntentSender intent, Intent fillInIntent, String resolvedType,
3667            IBinder resultTo, String resultWho, int requestCode,
3668            int flagsMask, int flagsValues, Bundle options) {
3669        enforceNotIsolatedCaller("startActivityIntentSender");
3670        // Refuse possible leaked file descriptors
3671        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3672            throw new IllegalArgumentException("File descriptors passed in Intent");
3673        }
3674
3675        IIntentSender sender = intent.getTarget();
3676        if (!(sender instanceof PendingIntentRecord)) {
3677            throw new IllegalArgumentException("Bad PendingIntent object");
3678        }
3679
3680        PendingIntentRecord pir = (PendingIntentRecord)sender;
3681
3682        synchronized (this) {
3683            // If this is coming from the currently resumed activity, it is
3684            // effectively saying that app switches are allowed at this point.
3685            final ActivityStack stack = getFocusedStack();
3686            if (stack.mResumedActivity != null &&
3687                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3688                mAppSwitchesAllowedTime = 0;
3689            }
3690        }
3691        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3692                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3693        return ret;
3694    }
3695
3696    @Override
3697    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3698            Intent intent, String resolvedType, IVoiceInteractionSession session,
3699            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3700            Bundle options, int userId) {
3701        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3702                != PackageManager.PERMISSION_GRANTED) {
3703            String msg = "Permission Denial: startVoiceActivity() from pid="
3704                    + Binder.getCallingPid()
3705                    + ", uid=" + Binder.getCallingUid()
3706                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3707            Slog.w(TAG, msg);
3708            throw new SecurityException(msg);
3709        }
3710        if (session == null || interactor == null) {
3711            throw new NullPointerException("null session or interactor");
3712        }
3713        userId = handleIncomingUser(callingPid, callingUid, userId,
3714                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3715        // TODO: Switch to user app stacks here.
3716        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3717                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3718                null, options, userId, null, null);
3719    }
3720
3721    @Override
3722    public boolean startNextMatchingActivity(IBinder callingActivity,
3723            Intent intent, Bundle options) {
3724        // Refuse possible leaked file descriptors
3725        if (intent != null && intent.hasFileDescriptors() == true) {
3726            throw new IllegalArgumentException("File descriptors passed in Intent");
3727        }
3728
3729        synchronized (this) {
3730            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3731            if (r == null) {
3732                ActivityOptions.abort(options);
3733                return false;
3734            }
3735            if (r.app == null || r.app.thread == null) {
3736                // The caller is not running...  d'oh!
3737                ActivityOptions.abort(options);
3738                return false;
3739            }
3740            intent = new Intent(intent);
3741            // The caller is not allowed to change the data.
3742            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3743            // And we are resetting to find the next component...
3744            intent.setComponent(null);
3745
3746            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3747
3748            ActivityInfo aInfo = null;
3749            try {
3750                List<ResolveInfo> resolves =
3751                    AppGlobals.getPackageManager().queryIntentActivities(
3752                            intent, r.resolvedType,
3753                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3754                            UserHandle.getCallingUserId());
3755
3756                // Look for the original activity in the list...
3757                final int N = resolves != null ? resolves.size() : 0;
3758                for (int i=0; i<N; i++) {
3759                    ResolveInfo rInfo = resolves.get(i);
3760                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3761                            && rInfo.activityInfo.name.equals(r.info.name)) {
3762                        // We found the current one...  the next matching is
3763                        // after it.
3764                        i++;
3765                        if (i<N) {
3766                            aInfo = resolves.get(i).activityInfo;
3767                        }
3768                        if (debug) {
3769                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3770                                    + "/" + r.info.name);
3771                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3772                                    + "/" + aInfo.name);
3773                        }
3774                        break;
3775                    }
3776                }
3777            } catch (RemoteException e) {
3778            }
3779
3780            if (aInfo == null) {
3781                // Nobody who is next!
3782                ActivityOptions.abort(options);
3783                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3784                return false;
3785            }
3786
3787            intent.setComponent(new ComponentName(
3788                    aInfo.applicationInfo.packageName, aInfo.name));
3789            intent.setFlags(intent.getFlags()&~(
3790                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3791                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3792                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3793                    Intent.FLAG_ACTIVITY_NEW_TASK));
3794
3795            // Okay now we need to start the new activity, replacing the
3796            // currently running activity.  This is a little tricky because
3797            // we want to start the new one as if the current one is finished,
3798            // but not finish the current one first so that there is no flicker.
3799            // And thus...
3800            final boolean wasFinishing = r.finishing;
3801            r.finishing = true;
3802
3803            // Propagate reply information over to the new activity.
3804            final ActivityRecord resultTo = r.resultTo;
3805            final String resultWho = r.resultWho;
3806            final int requestCode = r.requestCode;
3807            r.resultTo = null;
3808            if (resultTo != null) {
3809                resultTo.removeResultsLocked(r, resultWho, requestCode);
3810            }
3811
3812            final long origId = Binder.clearCallingIdentity();
3813            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3814                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3815                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3816                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3817            Binder.restoreCallingIdentity(origId);
3818
3819            r.finishing = wasFinishing;
3820            if (res != ActivityManager.START_SUCCESS) {
3821                return false;
3822            }
3823            return true;
3824        }
3825    }
3826
3827    @Override
3828    public final int startActivityFromRecents(int taskId, Bundle options) {
3829        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3830            String msg = "Permission Denial: startActivityFromRecents called without " +
3831                    START_TASKS_FROM_RECENTS;
3832            Slog.w(TAG, msg);
3833            throw new SecurityException(msg);
3834        }
3835        return startActivityFromRecentsInner(taskId, options);
3836    }
3837
3838    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3839        final TaskRecord task;
3840        final int callingUid;
3841        final String callingPackage;
3842        final Intent intent;
3843        final int userId;
3844        synchronized (this) {
3845            task = recentTaskForIdLocked(taskId);
3846            if (task == null) {
3847                throw new IllegalArgumentException("Task " + taskId + " not found.");
3848            }
3849            callingUid = task.mCallingUid;
3850            callingPackage = task.mCallingPackage;
3851            intent = task.intent;
3852            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3853            userId = task.userId;
3854        }
3855        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3856                options, userId, null, task);
3857    }
3858
3859    final int startActivityInPackage(int uid, String callingPackage,
3860            Intent intent, String resolvedType, IBinder resultTo,
3861            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3862            IActivityContainer container, TaskRecord inTask) {
3863
3864        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3865                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3866
3867        // TODO: Switch to user app stacks here.
3868        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3869                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3870                null, null, null, options, userId, container, inTask);
3871        return ret;
3872    }
3873
3874    @Override
3875    public final int startActivities(IApplicationThread caller, String callingPackage,
3876            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3877            int userId) {
3878        enforceNotIsolatedCaller("startActivities");
3879        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3880                false, ALLOW_FULL_ONLY, "startActivity", null);
3881        // TODO: Switch to user app stacks here.
3882        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3883                resolvedTypes, resultTo, options, userId);
3884        return ret;
3885    }
3886
3887    final int startActivitiesInPackage(int uid, String callingPackage,
3888            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3889            Bundle options, int userId) {
3890
3891        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3892                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3893        // TODO: Switch to user app stacks here.
3894        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3895                resultTo, options, userId);
3896        return ret;
3897    }
3898
3899    //explicitly remove thd old information in mRecentTasks when removing existing user.
3900    private void removeRecentTasksForUserLocked(int userId) {
3901        if(userId <= 0) {
3902            Slog.i(TAG, "Can't remove recent task on user " + userId);
3903            return;
3904        }
3905
3906        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3907            TaskRecord tr = mRecentTasks.get(i);
3908            if (tr.userId == userId) {
3909                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3910                        + " when finishing user" + userId);
3911                mRecentTasks.remove(i);
3912                tr.removedFromRecents(mTaskPersister);
3913            }
3914        }
3915
3916        // Remove tasks from persistent storage.
3917        mTaskPersister.wakeup(null, true);
3918    }
3919
3920    // Sort by taskId
3921    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3922        @Override
3923        public int compare(TaskRecord lhs, TaskRecord rhs) {
3924            return rhs.taskId - lhs.taskId;
3925        }
3926    };
3927
3928    // Extract the affiliates of the chain containing mRecentTasks[start].
3929    private int processNextAffiliateChain(int start) {
3930        final TaskRecord startTask = mRecentTasks.get(start);
3931        final int affiliateId = startTask.mAffiliatedTaskId;
3932
3933        // Quick identification of isolated tasks. I.e. those not launched behind.
3934        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3935                startTask.mNextAffiliate == null) {
3936            // There is still a slim chance that there are other tasks that point to this task
3937            // and that the chain is so messed up that this task no longer points to them but
3938            // the gain of this optimization outweighs the risk.
3939            startTask.inRecents = true;
3940            return start + 1;
3941        }
3942
3943        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3944        mTmpRecents.clear();
3945        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3946            final TaskRecord task = mRecentTasks.get(i);
3947            if (task.mAffiliatedTaskId == affiliateId) {
3948                mRecentTasks.remove(i);
3949                mTmpRecents.add(task);
3950            }
3951        }
3952
3953        // Sort them all by taskId. That is the order they were create in and that order will
3954        // always be correct.
3955        Collections.sort(mTmpRecents, mTaskRecordComparator);
3956
3957        // Go through and fix up the linked list.
3958        // The first one is the end of the chain and has no next.
3959        final TaskRecord first = mTmpRecents.get(0);
3960        first.inRecents = true;
3961        if (first.mNextAffiliate != null) {
3962            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3963            first.setNextAffiliate(null);
3964            mTaskPersister.wakeup(first, false);
3965        }
3966        // Everything in the middle is doubly linked from next to prev.
3967        final int tmpSize = mTmpRecents.size();
3968        for (int i = 0; i < tmpSize - 1; ++i) {
3969            final TaskRecord next = mTmpRecents.get(i);
3970            final TaskRecord prev = mTmpRecents.get(i + 1);
3971            if (next.mPrevAffiliate != prev) {
3972                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3973                        " setting prev=" + prev);
3974                next.setPrevAffiliate(prev);
3975                mTaskPersister.wakeup(next, false);
3976            }
3977            if (prev.mNextAffiliate != next) {
3978                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3979                        " setting next=" + next);
3980                prev.setNextAffiliate(next);
3981                mTaskPersister.wakeup(prev, false);
3982            }
3983            prev.inRecents = true;
3984        }
3985        // The last one is the beginning of the list and has no prev.
3986        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3987        if (last.mPrevAffiliate != null) {
3988            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3989            last.setPrevAffiliate(null);
3990            mTaskPersister.wakeup(last, false);
3991        }
3992
3993        // Insert the group back into mRecentTasks at start.
3994        mRecentTasks.addAll(start, mTmpRecents);
3995
3996        // Let the caller know where we left off.
3997        return start + tmpSize;
3998    }
3999
4000    /**
4001     * Update the recent tasks lists: make sure tasks should still be here (their
4002     * applications / activities still exist), update their availability, fixup ordering
4003     * of affiliations.
4004     */
4005    void cleanupRecentTasksLocked(int userId) {
4006        if (mRecentTasks == null) {
4007            // Happens when called from the packagemanager broadcast before boot.
4008            return;
4009        }
4010
4011        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
4012        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
4013        final IPackageManager pm = AppGlobals.getPackageManager();
4014        final ActivityInfo dummyAct = new ActivityInfo();
4015        final ApplicationInfo dummyApp = new ApplicationInfo();
4016
4017        int N = mRecentTasks.size();
4018
4019        int[] users = userId == UserHandle.USER_ALL
4020                ? getUsersLocked() : new int[] { userId };
4021        for (int user : users) {
4022            for (int i = 0; i < N; i++) {
4023                TaskRecord task = mRecentTasks.get(i);
4024                if (task.userId != user) {
4025                    // Only look at tasks for the user ID of interest.
4026                    continue;
4027                }
4028                if (task.autoRemoveRecents && task.getTopActivity() == null) {
4029                    // This situation is broken, and we should just get rid of it now.
4030                    mRecentTasks.remove(i);
4031                    task.removedFromRecents(mTaskPersister);
4032                    i--;
4033                    N--;
4034                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
4035                    continue;
4036                }
4037                // Check whether this activity is currently available.
4038                if (task.realActivity != null) {
4039                    ActivityInfo ai = availActCache.get(task.realActivity);
4040                    if (ai == null) {
4041                        try {
4042                            ai = pm.getActivityInfo(task.realActivity,
4043                                    PackageManager.GET_UNINSTALLED_PACKAGES
4044                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
4045                        } catch (RemoteException e) {
4046                            // Will never happen.
4047                            continue;
4048                        }
4049                        if (ai == null) {
4050                            ai = dummyAct;
4051                        }
4052                        availActCache.put(task.realActivity, ai);
4053                    }
4054                    if (ai == dummyAct) {
4055                        // This could be either because the activity no longer exists, or the
4056                        // app is temporarily gone.  For the former we want to remove the recents
4057                        // entry; for the latter we want to mark it as unavailable.
4058                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4059                        if (app == null) {
4060                            try {
4061                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4062                                        PackageManager.GET_UNINSTALLED_PACKAGES
4063                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4064                            } catch (RemoteException e) {
4065                                // Will never happen.
4066                                continue;
4067                            }
4068                            if (app == null) {
4069                                app = dummyApp;
4070                            }
4071                            availAppCache.put(task.realActivity.getPackageName(), app);
4072                        }
4073                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4074                            // Doesn't exist any more!  Good-bye.
4075                            mRecentTasks.remove(i);
4076                            task.removedFromRecents(mTaskPersister);
4077                            i--;
4078                            N--;
4079                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4080                            continue;
4081                        } else {
4082                            // Otherwise just not available for now.
4083                            if (task.isAvailable) {
4084                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4085                                        + task);
4086                            }
4087                            task.isAvailable = false;
4088                        }
4089                    } else {
4090                        if (!ai.enabled || !ai.applicationInfo.enabled
4091                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4092                            if (task.isAvailable) {
4093                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4094                                        + task + " (enabled=" + ai.enabled + "/"
4095                                        + ai.applicationInfo.enabled +  " flags="
4096                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4097                            }
4098                            task.isAvailable = false;
4099                        } else {
4100                            if (!task.isAvailable) {
4101                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4102                                        + task);
4103                            }
4104                            task.isAvailable = true;
4105                        }
4106                    }
4107                }
4108            }
4109        }
4110
4111        // Verify the affiliate chain for each task.
4112        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4113        }
4114
4115        mTmpRecents.clear();
4116        // mRecentTasks is now in sorted, affiliated order.
4117    }
4118
4119    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4120        int N = mRecentTasks.size();
4121        TaskRecord top = task;
4122        int topIndex = taskIndex;
4123        while (top.mNextAffiliate != null && topIndex > 0) {
4124            top = top.mNextAffiliate;
4125            topIndex--;
4126        }
4127        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4128                + topIndex + " from intial " + taskIndex);
4129        // Find the end of the chain, doing a sanity check along the way.
4130        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4131        int endIndex = topIndex;
4132        TaskRecord prev = top;
4133        while (endIndex < N) {
4134            TaskRecord cur = mRecentTasks.get(endIndex);
4135            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4136                    + endIndex + " " + cur);
4137            if (cur == top) {
4138                // Verify start of the chain.
4139                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4140                    Slog.wtf(TAG, "Bad chain @" + endIndex
4141                            + ": first task has next affiliate: " + prev);
4142                    sane = false;
4143                    break;
4144                }
4145            } else {
4146                // Verify middle of the chain's next points back to the one before.
4147                if (cur.mNextAffiliate != prev
4148                        || cur.mNextAffiliateTaskId != prev.taskId) {
4149                    Slog.wtf(TAG, "Bad chain @" + endIndex
4150                            + ": middle task " + cur + " @" + endIndex
4151                            + " has bad next affiliate "
4152                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4153                            + ", expected " + prev);
4154                    sane = false;
4155                    break;
4156                }
4157            }
4158            if (cur.mPrevAffiliateTaskId == -1) {
4159                // Chain ends here.
4160                if (cur.mPrevAffiliate != null) {
4161                    Slog.wtf(TAG, "Bad chain @" + endIndex
4162                            + ": last task " + cur + " has previous affiliate "
4163                            + cur.mPrevAffiliate);
4164                    sane = false;
4165                }
4166                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4167                break;
4168            } else {
4169                // Verify middle of the chain's prev points to a valid item.
4170                if (cur.mPrevAffiliate == null) {
4171                    Slog.wtf(TAG, "Bad chain @" + endIndex
4172                            + ": task " + cur + " has previous affiliate "
4173                            + cur.mPrevAffiliate + " but should be id "
4174                            + cur.mPrevAffiliate);
4175                    sane = false;
4176                    break;
4177                }
4178            }
4179            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4180                Slog.wtf(TAG, "Bad chain @" + endIndex
4181                        + ": task " + cur + " has affiliated id "
4182                        + cur.mAffiliatedTaskId + " but should be "
4183                        + task.mAffiliatedTaskId);
4184                sane = false;
4185                break;
4186            }
4187            prev = cur;
4188            endIndex++;
4189            if (endIndex >= N) {
4190                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4191                        + ": last task " + prev);
4192                sane = false;
4193                break;
4194            }
4195        }
4196        if (sane) {
4197            if (endIndex < taskIndex) {
4198                Slog.wtf(TAG, "Bad chain @" + endIndex
4199                        + ": did not extend to task " + task + " @" + taskIndex);
4200                sane = false;
4201            }
4202        }
4203        if (sane) {
4204            // All looks good, we can just move all of the affiliated tasks
4205            // to the top.
4206            for (int i=topIndex; i<=endIndex; i++) {
4207                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4208                        + " from " + i + " to " + (i-topIndex));
4209                TaskRecord cur = mRecentTasks.remove(i);
4210                mRecentTasks.add(i-topIndex, cur);
4211            }
4212            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4213                    + " to " + endIndex);
4214            return true;
4215        }
4216
4217        // Whoops, couldn't do it.
4218        return false;
4219    }
4220
4221    final void addRecentTaskLocked(TaskRecord task) {
4222        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4223                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4224
4225        int N = mRecentTasks.size();
4226        // Quick case: check if the top-most recent task is the same.
4227        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4228            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4229            return;
4230        }
4231        // Another quick case: check if this is part of a set of affiliated
4232        // tasks that are at the top.
4233        if (isAffiliated && N > 0 && task.inRecents
4234                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4235            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4236                    + " at top when adding " + task);
4237            return;
4238        }
4239        // Another quick case: never add voice sessions.
4240        if (task.voiceSession != null) {
4241            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4242            return;
4243        }
4244
4245        boolean needAffiliationFix = false;
4246
4247        // Slightly less quick case: the task is already in recents, so all we need
4248        // to do is move it.
4249        if (task.inRecents) {
4250            int taskIndex = mRecentTasks.indexOf(task);
4251            if (taskIndex >= 0) {
4252                if (!isAffiliated) {
4253                    // Simple case: this is not an affiliated task, so we just move it to the front.
4254                    mRecentTasks.remove(taskIndex);
4255                    mRecentTasks.add(0, task);
4256                    notifyTaskPersisterLocked(task, false);
4257                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4258                            + " from " + taskIndex);
4259                    return;
4260                } else {
4261                    // More complicated: need to keep all affiliated tasks together.
4262                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4263                        // All went well.
4264                        return;
4265                    }
4266
4267                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4268                    // everything and then go through our general path of adding a new task.
4269                    needAffiliationFix = true;
4270                }
4271            } else {
4272                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4273                needAffiliationFix = true;
4274            }
4275        }
4276
4277        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4278        trimRecentsForTask(task, true);
4279
4280        N = mRecentTasks.size();
4281        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4282            final TaskRecord tr = mRecentTasks.remove(N - 1);
4283            tr.removedFromRecents(mTaskPersister);
4284            N--;
4285        }
4286        task.inRecents = true;
4287        if (!isAffiliated || needAffiliationFix) {
4288            // If this is a simple non-affiliated task, or we had some failure trying to
4289            // handle it as part of an affilated task, then just place it at the top.
4290            mRecentTasks.add(0, task);
4291        } else if (isAffiliated) {
4292            // If this is a new affiliated task, then move all of the affiliated tasks
4293            // to the front and insert this new one.
4294            TaskRecord other = task.mNextAffiliate;
4295            if (other == null) {
4296                other = task.mPrevAffiliate;
4297            }
4298            if (other != null) {
4299                int otherIndex = mRecentTasks.indexOf(other);
4300                if (otherIndex >= 0) {
4301                    // Insert new task at appropriate location.
4302                    int taskIndex;
4303                    if (other == task.mNextAffiliate) {
4304                        // We found the index of our next affiliation, which is who is
4305                        // before us in the list, so add after that point.
4306                        taskIndex = otherIndex+1;
4307                    } else {
4308                        // We found the index of our previous affiliation, which is who is
4309                        // after us in the list, so add at their position.
4310                        taskIndex = otherIndex;
4311                    }
4312                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4313                            + taskIndex + ": " + task);
4314                    mRecentTasks.add(taskIndex, task);
4315
4316                    // Now move everything to the front.
4317                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4318                        // All went well.
4319                        return;
4320                    }
4321
4322                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4323                    // everything and then go through our general path of adding a new task.
4324                    needAffiliationFix = true;
4325                } else {
4326                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4327                            + other);
4328                    needAffiliationFix = true;
4329                }
4330            } else {
4331                if (DEBUG_RECENTS) Slog.d(TAG,
4332                        "addRecent: adding affiliated task without next/prev:" + task);
4333                needAffiliationFix = true;
4334            }
4335        }
4336        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4337
4338        if (needAffiliationFix) {
4339            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4340            cleanupRecentTasksLocked(task.userId);
4341        }
4342    }
4343
4344    /**
4345     * If needed, remove oldest existing entries in recents that are for the same kind
4346     * of task as the given one.
4347     */
4348    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4349        int N = mRecentTasks.size();
4350        final Intent intent = task.intent;
4351        final boolean document = intent != null && intent.isDocument();
4352
4353        int maxRecents = task.maxRecents - 1;
4354        for (int i=0; i<N; i++) {
4355            final TaskRecord tr = mRecentTasks.get(i);
4356            if (task != tr) {
4357                if (task.userId != tr.userId) {
4358                    continue;
4359                }
4360                if (i > MAX_RECENT_BITMAPS) {
4361                    tr.freeLastThumbnail();
4362                }
4363                final Intent trIntent = tr.intent;
4364                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4365                    (intent == null || !intent.filterEquals(trIntent))) {
4366                    continue;
4367                }
4368                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4369                if (document && trIsDocument) {
4370                    // These are the same document activity (not necessarily the same doc).
4371                    if (maxRecents > 0) {
4372                        --maxRecents;
4373                        continue;
4374                    }
4375                    // Hit the maximum number of documents for this task. Fall through
4376                    // and remove this document from recents.
4377                } else if (document || trIsDocument) {
4378                    // Only one of these is a document. Not the droid we're looking for.
4379                    continue;
4380                }
4381            }
4382
4383            if (!doTrim) {
4384                // If the caller is not actually asking for a trim, just tell them we reached
4385                // a point where the trim would happen.
4386                return i;
4387            }
4388
4389            // Either task and tr are the same or, their affinities match or their intents match
4390            // and neither of them is a document, or they are documents using the same activity
4391            // and their maxRecents has been reached.
4392            tr.disposeThumbnail();
4393            mRecentTasks.remove(i);
4394            if (task != tr) {
4395                tr.removedFromRecents(mTaskPersister);
4396            }
4397            i--;
4398            N--;
4399            if (task.intent == null) {
4400                // If the new recent task we are adding is not fully
4401                // specified, then replace it with the existing recent task.
4402                task = tr;
4403            }
4404            notifyTaskPersisterLocked(tr, false);
4405        }
4406
4407        return -1;
4408    }
4409
4410    @Override
4411    public void reportActivityFullyDrawn(IBinder token) {
4412        synchronized (this) {
4413            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4414            if (r == null) {
4415                return;
4416            }
4417            r.reportFullyDrawnLocked();
4418        }
4419    }
4420
4421    @Override
4422    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4423        synchronized (this) {
4424            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4425            if (r == null) {
4426                return;
4427            }
4428            final long origId = Binder.clearCallingIdentity();
4429            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4430            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4431                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4432            if (config != null) {
4433                r.frozenBeforeDestroy = true;
4434                if (!updateConfigurationLocked(config, r, false, false)) {
4435                    mStackSupervisor.resumeTopActivitiesLocked();
4436                }
4437            }
4438            Binder.restoreCallingIdentity(origId);
4439        }
4440    }
4441
4442    @Override
4443    public int getRequestedOrientation(IBinder token) {
4444        synchronized (this) {
4445            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4446            if (r == null) {
4447                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4448            }
4449            return mWindowManager.getAppOrientation(r.appToken);
4450        }
4451    }
4452
4453    /**
4454     * This is the internal entry point for handling Activity.finish().
4455     *
4456     * @param token The Binder token referencing the Activity we want to finish.
4457     * @param resultCode Result code, if any, from this Activity.
4458     * @param resultData Result data (Intent), if any, from this Activity.
4459     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4460     *            the root Activity in the task.
4461     *
4462     * @return Returns true if the activity successfully finished, or false if it is still running.
4463     */
4464    @Override
4465    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4466            boolean finishTask) {
4467        // Refuse possible leaked file descriptors
4468        if (resultData != null && resultData.hasFileDescriptors() == true) {
4469            throw new IllegalArgumentException("File descriptors passed in Intent");
4470        }
4471
4472        synchronized(this) {
4473            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4474            if (r == null) {
4475                return true;
4476            }
4477            // Keep track of the root activity of the task before we finish it
4478            TaskRecord tr = r.task;
4479            ActivityRecord rootR = tr.getRootActivity();
4480            // Do not allow task to finish in Lock Task mode.
4481            if (tr == mStackSupervisor.mLockTaskModeTask) {
4482                if (rootR == r) {
4483                    mStackSupervisor.showLockTaskToast();
4484                    return false;
4485                }
4486            }
4487            if (mController != null) {
4488                // Find the first activity that is not finishing.
4489                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4490                if (next != null) {
4491                    // ask watcher if this is allowed
4492                    boolean resumeOK = true;
4493                    try {
4494                        resumeOK = mController.activityResuming(next.packageName);
4495                    } catch (RemoteException e) {
4496                        mController = null;
4497                        Watchdog.getInstance().setActivityController(null);
4498                    }
4499
4500                    if (!resumeOK) {
4501                        return false;
4502                    }
4503                }
4504            }
4505            final long origId = Binder.clearCallingIdentity();
4506            try {
4507                boolean res;
4508                if (finishTask && r == rootR) {
4509                    // If requested, remove the task that is associated to this activity only if it
4510                    // was the root activity in the task.  The result code and data is ignored because
4511                    // we don't support returning them across task boundaries.
4512                    res = removeTaskByIdLocked(tr.taskId, 0);
4513                } else {
4514                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4515                            resultData, "app-request", true);
4516                }
4517                return res;
4518            } finally {
4519                Binder.restoreCallingIdentity(origId);
4520            }
4521        }
4522    }
4523
4524    @Override
4525    public final void finishHeavyWeightApp() {
4526        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4527                != PackageManager.PERMISSION_GRANTED) {
4528            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4529                    + Binder.getCallingPid()
4530                    + ", uid=" + Binder.getCallingUid()
4531                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4532            Slog.w(TAG, msg);
4533            throw new SecurityException(msg);
4534        }
4535
4536        synchronized(this) {
4537            if (mHeavyWeightProcess == null) {
4538                return;
4539            }
4540
4541            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4542                    mHeavyWeightProcess.activities);
4543            for (int i=0; i<activities.size(); i++) {
4544                ActivityRecord r = activities.get(i);
4545                if (!r.finishing) {
4546                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4547                            null, "finish-heavy", true);
4548                }
4549            }
4550
4551            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4552                    mHeavyWeightProcess.userId, 0));
4553            mHeavyWeightProcess = null;
4554        }
4555    }
4556
4557    @Override
4558    public void crashApplication(int uid, int initialPid, String packageName,
4559            String message) {
4560        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4561                != PackageManager.PERMISSION_GRANTED) {
4562            String msg = "Permission Denial: crashApplication() from pid="
4563                    + Binder.getCallingPid()
4564                    + ", uid=" + Binder.getCallingUid()
4565                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4566            Slog.w(TAG, msg);
4567            throw new SecurityException(msg);
4568        }
4569
4570        synchronized(this) {
4571            ProcessRecord proc = null;
4572
4573            // Figure out which process to kill.  We don't trust that initialPid
4574            // still has any relation to current pids, so must scan through the
4575            // list.
4576            synchronized (mPidsSelfLocked) {
4577                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4578                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4579                    if (p.uid != uid) {
4580                        continue;
4581                    }
4582                    if (p.pid == initialPid) {
4583                        proc = p;
4584                        break;
4585                    }
4586                    if (p.pkgList.containsKey(packageName)) {
4587                        proc = p;
4588                    }
4589                }
4590            }
4591
4592            if (proc == null) {
4593                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4594                        + " initialPid=" + initialPid
4595                        + " packageName=" + packageName);
4596                return;
4597            }
4598
4599            if (proc.thread != null) {
4600                if (proc.pid == Process.myPid()) {
4601                    Log.w(TAG, "crashApplication: trying to crash self!");
4602                    return;
4603                }
4604                long ident = Binder.clearCallingIdentity();
4605                try {
4606                    proc.thread.scheduleCrash(message);
4607                } catch (RemoteException e) {
4608                }
4609                Binder.restoreCallingIdentity(ident);
4610            }
4611        }
4612    }
4613
4614    @Override
4615    public final void finishSubActivity(IBinder token, String resultWho,
4616            int requestCode) {
4617        synchronized(this) {
4618            final long origId = Binder.clearCallingIdentity();
4619            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4620            if (r != null) {
4621                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4622            }
4623            Binder.restoreCallingIdentity(origId);
4624        }
4625    }
4626
4627    @Override
4628    public boolean finishActivityAffinity(IBinder token) {
4629        synchronized(this) {
4630            final long origId = Binder.clearCallingIdentity();
4631            try {
4632                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4633
4634                ActivityRecord rootR = r.task.getRootActivity();
4635                // Do not allow task to finish in Lock Task mode.
4636                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4637                    if (rootR == r) {
4638                        mStackSupervisor.showLockTaskToast();
4639                        return false;
4640                    }
4641                }
4642                boolean res = false;
4643                if (r != null) {
4644                    res = r.task.stack.finishActivityAffinityLocked(r);
4645                }
4646                return res;
4647            } finally {
4648                Binder.restoreCallingIdentity(origId);
4649            }
4650        }
4651    }
4652
4653    @Override
4654    public void finishVoiceTask(IVoiceInteractionSession session) {
4655        synchronized(this) {
4656            final long origId = Binder.clearCallingIdentity();
4657            try {
4658                mStackSupervisor.finishVoiceTask(session);
4659            } finally {
4660                Binder.restoreCallingIdentity(origId);
4661            }
4662        }
4663
4664    }
4665
4666    @Override
4667    public boolean releaseActivityInstance(IBinder token) {
4668        synchronized(this) {
4669            final long origId = Binder.clearCallingIdentity();
4670            try {
4671                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4672                if (r.task == null || r.task.stack == null) {
4673                    return false;
4674                }
4675                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4676            } finally {
4677                Binder.restoreCallingIdentity(origId);
4678            }
4679        }
4680    }
4681
4682    @Override
4683    public void releaseSomeActivities(IApplicationThread appInt) {
4684        synchronized(this) {
4685            final long origId = Binder.clearCallingIdentity();
4686            try {
4687                ProcessRecord app = getRecordForAppLocked(appInt);
4688                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4689            } finally {
4690                Binder.restoreCallingIdentity(origId);
4691            }
4692        }
4693    }
4694
4695    @Override
4696    public boolean willActivityBeVisible(IBinder token) {
4697        synchronized(this) {
4698            ActivityStack stack = ActivityRecord.getStackLocked(token);
4699            if (stack != null) {
4700                return stack.willActivityBeVisibleLocked(token);
4701            }
4702            return false;
4703        }
4704    }
4705
4706    @Override
4707    public void overridePendingTransition(IBinder token, String packageName,
4708            int enterAnim, int exitAnim) {
4709        synchronized(this) {
4710            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4711            if (self == null) {
4712                return;
4713            }
4714
4715            final long origId = Binder.clearCallingIdentity();
4716
4717            if (self.state == ActivityState.RESUMED
4718                    || self.state == ActivityState.PAUSING) {
4719                mWindowManager.overridePendingAppTransition(packageName,
4720                        enterAnim, exitAnim, null);
4721            }
4722
4723            Binder.restoreCallingIdentity(origId);
4724        }
4725    }
4726
4727    /**
4728     * Main function for removing an existing process from the activity manager
4729     * as a result of that process going away.  Clears out all connections
4730     * to the process.
4731     */
4732    private final void handleAppDiedLocked(ProcessRecord app,
4733            boolean restarting, boolean allowRestart) {
4734        int pid = app.pid;
4735        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4736        if (!kept && !restarting) {
4737            removeLruProcessLocked(app);
4738            if (pid > 0) {
4739                ProcessList.remove(pid);
4740            }
4741        }
4742
4743        if (mProfileProc == app) {
4744            clearProfilerLocked();
4745        }
4746
4747        // Remove this application's activities from active lists.
4748        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4749
4750        app.activities.clear();
4751
4752        if (app.instrumentationClass != null) {
4753            Slog.w(TAG, "Crash of app " + app.processName
4754                  + " running instrumentation " + app.instrumentationClass);
4755            Bundle info = new Bundle();
4756            info.putString("shortMsg", "Process crashed.");
4757            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4758        }
4759
4760        if (!restarting) {
4761            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4762                // If there was nothing to resume, and we are not already
4763                // restarting this process, but there is a visible activity that
4764                // is hosted by the process...  then make sure all visible
4765                // activities are running, taking care of restarting this
4766                // process.
4767                if (hasVisibleActivities) {
4768                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4769                }
4770            }
4771        }
4772    }
4773
4774    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4775        IBinder threadBinder = thread.asBinder();
4776        // Find the application record.
4777        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4778            ProcessRecord rec = mLruProcesses.get(i);
4779            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4780                return i;
4781            }
4782        }
4783        return -1;
4784    }
4785
4786    final ProcessRecord getRecordForAppLocked(
4787            IApplicationThread thread) {
4788        if (thread == null) {
4789            return null;
4790        }
4791
4792        int appIndex = getLRURecordIndexForAppLocked(thread);
4793        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4794    }
4795
4796    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4797        // If there are no longer any background processes running,
4798        // and the app that died was not running instrumentation,
4799        // then tell everyone we are now low on memory.
4800        boolean haveBg = false;
4801        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4802            ProcessRecord rec = mLruProcesses.get(i);
4803            if (rec.thread != null
4804                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4805                haveBg = true;
4806                break;
4807            }
4808        }
4809
4810        if (!haveBg) {
4811            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4812            if (doReport) {
4813                long now = SystemClock.uptimeMillis();
4814                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4815                    doReport = false;
4816                } else {
4817                    mLastMemUsageReportTime = now;
4818                }
4819            }
4820            final ArrayList<ProcessMemInfo> memInfos
4821                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4822            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4823            long now = SystemClock.uptimeMillis();
4824            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4825                ProcessRecord rec = mLruProcesses.get(i);
4826                if (rec == dyingProc || rec.thread == null) {
4827                    continue;
4828                }
4829                if (doReport) {
4830                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4831                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4832                }
4833                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4834                    // The low memory report is overriding any current
4835                    // state for a GC request.  Make sure to do
4836                    // heavy/important/visible/foreground processes first.
4837                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4838                        rec.lastRequestedGc = 0;
4839                    } else {
4840                        rec.lastRequestedGc = rec.lastLowMemory;
4841                    }
4842                    rec.reportLowMemory = true;
4843                    rec.lastLowMemory = now;
4844                    mProcessesToGc.remove(rec);
4845                    addProcessToGcListLocked(rec);
4846                }
4847            }
4848            if (doReport) {
4849                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4850                mHandler.sendMessage(msg);
4851            }
4852            scheduleAppGcsLocked();
4853        }
4854    }
4855
4856    final void appDiedLocked(ProcessRecord app) {
4857       appDiedLocked(app, app.pid, app.thread);
4858    }
4859
4860    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4861        // First check if this ProcessRecord is actually active for the pid.
4862        synchronized (mPidsSelfLocked) {
4863            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4864            if (curProc != app) {
4865                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4866                return;
4867            }
4868        }
4869
4870        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4871        synchronized (stats) {
4872            stats.noteProcessDiedLocked(app.info.uid, pid);
4873        }
4874
4875        Process.killProcessQuiet(pid);
4876        Process.killProcessGroup(app.info.uid, pid);
4877        app.killed = true;
4878
4879        // Clean up already done if the process has been re-started.
4880        if (app.pid == pid && app.thread != null &&
4881                app.thread.asBinder() == thread.asBinder()) {
4882            boolean doLowMem = app.instrumentationClass == null;
4883            boolean doOomAdj = doLowMem;
4884            if (!app.killedByAm) {
4885                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4886                        + ") has died");
4887                mAllowLowerMemLevel = true;
4888            } else {
4889                // Note that we always want to do oom adj to update our state with the
4890                // new number of procs.
4891                mAllowLowerMemLevel = false;
4892                doLowMem = false;
4893            }
4894            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4895            if (DEBUG_CLEANUP) Slog.v(
4896                TAG, "Dying app: " + app + ", pid: " + pid
4897                + ", thread: " + thread.asBinder());
4898            handleAppDiedLocked(app, false, true);
4899
4900            if (doOomAdj) {
4901                updateOomAdjLocked();
4902            }
4903            if (doLowMem) {
4904                doLowMemReportIfNeededLocked(app);
4905            }
4906        } else if (app.pid != pid) {
4907            // A new process has already been started.
4908            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4909                    + ") has died and restarted (pid " + app.pid + ").");
4910            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4911        } else if (DEBUG_PROCESSES) {
4912            Slog.d(TAG, "Received spurious death notification for thread "
4913                    + thread.asBinder());
4914        }
4915    }
4916
4917    /**
4918     * If a stack trace dump file is configured, dump process stack traces.
4919     * @param clearTraces causes the dump file to be erased prior to the new
4920     *    traces being written, if true; when false, the new traces will be
4921     *    appended to any existing file content.
4922     * @param firstPids of dalvik VM processes to dump stack traces for first
4923     * @param lastPids of dalvik VM processes to dump stack traces for last
4924     * @param nativeProcs optional list of native process names to dump stack crawls
4925     * @return file containing stack traces, or null if no dump file is configured
4926     */
4927    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4928            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4929        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4930        if (tracesPath == null || tracesPath.length() == 0) {
4931            return null;
4932        }
4933
4934        File tracesFile = new File(tracesPath);
4935        try {
4936            File tracesDir = tracesFile.getParentFile();
4937            if (!tracesDir.exists()) {
4938                tracesDir.mkdirs();
4939                if (!SELinux.restorecon(tracesDir)) {
4940                    return null;
4941                }
4942            }
4943            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4944
4945            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4946            tracesFile.createNewFile();
4947            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4948        } catch (IOException e) {
4949            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4950            return null;
4951        }
4952
4953        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4954        return tracesFile;
4955    }
4956
4957    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4958            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4959        // Use a FileObserver to detect when traces finish writing.
4960        // The order of traces is considered important to maintain for legibility.
4961        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4962            @Override
4963            public synchronized void onEvent(int event, String path) { notify(); }
4964        };
4965
4966        try {
4967            observer.startWatching();
4968
4969            // First collect all of the stacks of the most important pids.
4970            if (firstPids != null) {
4971                try {
4972                    int num = firstPids.size();
4973                    for (int i = 0; i < num; i++) {
4974                        synchronized (observer) {
4975                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4976                            observer.wait(200);  // Wait for write-close, give up after 200msec
4977                        }
4978                    }
4979                } catch (InterruptedException e) {
4980                    Slog.wtf(TAG, e);
4981                }
4982            }
4983
4984            // Next collect the stacks of the native pids
4985            if (nativeProcs != null) {
4986                int[] pids = Process.getPidsForCommands(nativeProcs);
4987                if (pids != null) {
4988                    for (int pid : pids) {
4989                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4990                    }
4991                }
4992            }
4993
4994            // Lastly, measure CPU usage.
4995            if (processCpuTracker != null) {
4996                processCpuTracker.init();
4997                System.gc();
4998                processCpuTracker.update();
4999                try {
5000                    synchronized (processCpuTracker) {
5001                        processCpuTracker.wait(500); // measure over 1/2 second.
5002                    }
5003                } catch (InterruptedException e) {
5004                }
5005                processCpuTracker.update();
5006
5007                // We'll take the stack crawls of just the top apps using CPU.
5008                final int N = processCpuTracker.countWorkingStats();
5009                int numProcs = 0;
5010                for (int i=0; i<N && numProcs<5; i++) {
5011                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5012                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5013                        numProcs++;
5014                        try {
5015                            synchronized (observer) {
5016                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5017                                observer.wait(200);  // Wait for write-close, give up after 200msec
5018                            }
5019                        } catch (InterruptedException e) {
5020                            Slog.wtf(TAG, e);
5021                        }
5022
5023                    }
5024                }
5025            }
5026        } finally {
5027            observer.stopWatching();
5028        }
5029    }
5030
5031    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5032        if (true || IS_USER_BUILD) {
5033            return;
5034        }
5035        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5036        if (tracesPath == null || tracesPath.length() == 0) {
5037            return;
5038        }
5039
5040        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5041        StrictMode.allowThreadDiskWrites();
5042        try {
5043            final File tracesFile = new File(tracesPath);
5044            final File tracesDir = tracesFile.getParentFile();
5045            final File tracesTmp = new File(tracesDir, "__tmp__");
5046            try {
5047                if (!tracesDir.exists()) {
5048                    tracesDir.mkdirs();
5049                    if (!SELinux.restorecon(tracesDir.getPath())) {
5050                        return;
5051                    }
5052                }
5053                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
5054
5055                if (tracesFile.exists()) {
5056                    tracesTmp.delete();
5057                    tracesFile.renameTo(tracesTmp);
5058                }
5059                StringBuilder sb = new StringBuilder();
5060                Time tobj = new Time();
5061                tobj.set(System.currentTimeMillis());
5062                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5063                sb.append(": ");
5064                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5065                sb.append(" since ");
5066                sb.append(msg);
5067                FileOutputStream fos = new FileOutputStream(tracesFile);
5068                fos.write(sb.toString().getBytes());
5069                if (app == null) {
5070                    fos.write("\n*** No application process!".getBytes());
5071                }
5072                fos.close();
5073                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5074            } catch (IOException e) {
5075                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5076                return;
5077            }
5078
5079            if (app != null) {
5080                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5081                firstPids.add(app.pid);
5082                dumpStackTraces(tracesPath, firstPids, null, null, null);
5083            }
5084
5085            File lastTracesFile = null;
5086            File curTracesFile = null;
5087            for (int i=9; i>=0; i--) {
5088                String name = String.format(Locale.US, "slow%02d.txt", i);
5089                curTracesFile = new File(tracesDir, name);
5090                if (curTracesFile.exists()) {
5091                    if (lastTracesFile != null) {
5092                        curTracesFile.renameTo(lastTracesFile);
5093                    } else {
5094                        curTracesFile.delete();
5095                    }
5096                }
5097                lastTracesFile = curTracesFile;
5098            }
5099            tracesFile.renameTo(curTracesFile);
5100            if (tracesTmp.exists()) {
5101                tracesTmp.renameTo(tracesFile);
5102            }
5103        } finally {
5104            StrictMode.setThreadPolicy(oldPolicy);
5105        }
5106    }
5107
5108    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5109            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5110        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5111        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5112
5113        if (mController != null) {
5114            try {
5115                // 0 == continue, -1 = kill process immediately
5116                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5117                if (res < 0 && app.pid != MY_PID) {
5118                    app.kill("anr", true);
5119                }
5120            } catch (RemoteException e) {
5121                mController = null;
5122                Watchdog.getInstance().setActivityController(null);
5123            }
5124        }
5125
5126        long anrTime = SystemClock.uptimeMillis();
5127        if (MONITOR_CPU_USAGE) {
5128            updateCpuStatsNow();
5129        }
5130
5131        synchronized (this) {
5132            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5133            if (mShuttingDown) {
5134                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5135                return;
5136            } else if (app.notResponding) {
5137                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5138                return;
5139            } else if (app.crashing) {
5140                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5141                return;
5142            }
5143
5144            // In case we come through here for the same app before completing
5145            // this one, mark as anring now so we will bail out.
5146            app.notResponding = true;
5147
5148            // Log the ANR to the event log.
5149            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5150                    app.processName, app.info.flags, annotation);
5151
5152            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5153            firstPids.add(app.pid);
5154
5155            int parentPid = app.pid;
5156            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5157            if (parentPid != app.pid) firstPids.add(parentPid);
5158
5159            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5160
5161            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5162                ProcessRecord r = mLruProcesses.get(i);
5163                if (r != null && r.thread != null) {
5164                    int pid = r.pid;
5165                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5166                        if (r.persistent) {
5167                            firstPids.add(pid);
5168                        } else {
5169                            lastPids.put(pid, Boolean.TRUE);
5170                        }
5171                    }
5172                }
5173            }
5174        }
5175
5176        // Log the ANR to the main log.
5177        StringBuilder info = new StringBuilder();
5178        info.setLength(0);
5179        info.append("ANR in ").append(app.processName);
5180        if (activity != null && activity.shortComponentName != null) {
5181            info.append(" (").append(activity.shortComponentName).append(")");
5182        }
5183        info.append("\n");
5184        info.append("PID: ").append(app.pid).append("\n");
5185        if (annotation != null) {
5186            info.append("Reason: ").append(annotation).append("\n");
5187        }
5188        if (parent != null && parent != activity) {
5189            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5190        }
5191
5192        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5193
5194        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5195                NATIVE_STACKS_OF_INTEREST);
5196
5197        String cpuInfo = null;
5198        if (MONITOR_CPU_USAGE) {
5199            updateCpuStatsNow();
5200            synchronized (mProcessCpuTracker) {
5201                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5202            }
5203            info.append(processCpuTracker.printCurrentLoad());
5204            info.append(cpuInfo);
5205        }
5206
5207        info.append(processCpuTracker.printCurrentState(anrTime));
5208
5209        Slog.e(TAG, info.toString());
5210        if (tracesFile == null) {
5211            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5212            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5213        }
5214
5215        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5216                cpuInfo, tracesFile, null);
5217
5218        if (mController != null) {
5219            try {
5220                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5221                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5222                if (res != 0) {
5223                    if (res < 0 && app.pid != MY_PID) {
5224                        app.kill("anr", true);
5225                    } else {
5226                        synchronized (this) {
5227                            mServices.scheduleServiceTimeoutLocked(app);
5228                        }
5229                    }
5230                    return;
5231                }
5232            } catch (RemoteException e) {
5233                mController = null;
5234                Watchdog.getInstance().setActivityController(null);
5235            }
5236        }
5237
5238        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5239        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5240                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5241
5242        synchronized (this) {
5243            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5244                app.kill("bg anr", true);
5245                return;
5246            }
5247
5248            // Set the app's notResponding state, and look up the errorReportReceiver
5249            makeAppNotRespondingLocked(app,
5250                    activity != null ? activity.shortComponentName : null,
5251                    annotation != null ? "ANR " + annotation : "ANR",
5252                    info.toString());
5253
5254            // Bring up the infamous App Not Responding dialog
5255            Message msg = Message.obtain();
5256            HashMap<String, Object> map = new HashMap<String, Object>();
5257            msg.what = SHOW_NOT_RESPONDING_MSG;
5258            msg.obj = map;
5259            msg.arg1 = aboveSystem ? 1 : 0;
5260            map.put("app", app);
5261            if (activity != null) {
5262                map.put("activity", activity);
5263            }
5264
5265            mHandler.sendMessage(msg);
5266        }
5267    }
5268
5269    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5270        if (!mLaunchWarningShown) {
5271            mLaunchWarningShown = true;
5272            mHandler.post(new Runnable() {
5273                @Override
5274                public void run() {
5275                    synchronized (ActivityManagerService.this) {
5276                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5277                        d.show();
5278                        mHandler.postDelayed(new Runnable() {
5279                            @Override
5280                            public void run() {
5281                                synchronized (ActivityManagerService.this) {
5282                                    d.dismiss();
5283                                    mLaunchWarningShown = false;
5284                                }
5285                            }
5286                        }, 4000);
5287                    }
5288                }
5289            });
5290        }
5291    }
5292
5293    @Override
5294    public boolean clearApplicationUserData(final String packageName,
5295            final IPackageDataObserver observer, int userId) {
5296        enforceNotIsolatedCaller("clearApplicationUserData");
5297        int uid = Binder.getCallingUid();
5298        int pid = Binder.getCallingPid();
5299        userId = handleIncomingUser(pid, uid,
5300                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5301        long callingId = Binder.clearCallingIdentity();
5302        try {
5303            IPackageManager pm = AppGlobals.getPackageManager();
5304            int pkgUid = -1;
5305            synchronized(this) {
5306                try {
5307                    pkgUid = pm.getPackageUid(packageName, userId);
5308                } catch (RemoteException e) {
5309                }
5310                if (pkgUid == -1) {
5311                    Slog.w(TAG, "Invalid packageName: " + packageName);
5312                    if (observer != null) {
5313                        try {
5314                            observer.onRemoveCompleted(packageName, false);
5315                        } catch (RemoteException e) {
5316                            Slog.i(TAG, "Observer no longer exists.");
5317                        }
5318                    }
5319                    return false;
5320                }
5321                if (uid == pkgUid || checkComponentPermission(
5322                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5323                        pid, uid, -1, true)
5324                        == PackageManager.PERMISSION_GRANTED) {
5325                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5326                } else {
5327                    throw new SecurityException("PID " + pid + " does not have permission "
5328                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5329                                    + " of package " + packageName);
5330                }
5331
5332                // Remove all tasks match the cleared application package and user
5333                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5334                    final TaskRecord tr = mRecentTasks.get(i);
5335                    final String taskPackageName =
5336                            tr.getBaseIntent().getComponent().getPackageName();
5337                    if (tr.userId != userId) continue;
5338                    if (!taskPackageName.equals(packageName)) continue;
5339                    removeTaskByIdLocked(tr.taskId, 0);
5340                }
5341            }
5342
5343            try {
5344                // Clear application user data
5345                pm.clearApplicationUserData(packageName, observer, userId);
5346
5347                synchronized(this) {
5348                    // Remove all permissions granted from/to this package
5349                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5350                }
5351
5352                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5353                        Uri.fromParts("package", packageName, null));
5354                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5355                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5356                        null, null, 0, null, null, null, false, false, userId);
5357            } catch (RemoteException e) {
5358            }
5359        } finally {
5360            Binder.restoreCallingIdentity(callingId);
5361        }
5362        return true;
5363    }
5364
5365    @Override
5366    public void killBackgroundProcesses(final String packageName, int userId) {
5367        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5368                != PackageManager.PERMISSION_GRANTED &&
5369                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5370                        != PackageManager.PERMISSION_GRANTED) {
5371            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5372                    + Binder.getCallingPid()
5373                    + ", uid=" + Binder.getCallingUid()
5374                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5375            Slog.w(TAG, msg);
5376            throw new SecurityException(msg);
5377        }
5378
5379        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5380                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5381        long callingId = Binder.clearCallingIdentity();
5382        try {
5383            IPackageManager pm = AppGlobals.getPackageManager();
5384            synchronized(this) {
5385                int appId = -1;
5386                try {
5387                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5388                } catch (RemoteException e) {
5389                }
5390                if (appId == -1) {
5391                    Slog.w(TAG, "Invalid packageName: " + packageName);
5392                    return;
5393                }
5394                killPackageProcessesLocked(packageName, appId, userId,
5395                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5396            }
5397        } finally {
5398            Binder.restoreCallingIdentity(callingId);
5399        }
5400    }
5401
5402    @Override
5403    public void killAllBackgroundProcesses() {
5404        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5405                != PackageManager.PERMISSION_GRANTED) {
5406            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5407                    + Binder.getCallingPid()
5408                    + ", uid=" + Binder.getCallingUid()
5409                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5410            Slog.w(TAG, msg);
5411            throw new SecurityException(msg);
5412        }
5413
5414        long callingId = Binder.clearCallingIdentity();
5415        try {
5416            synchronized(this) {
5417                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5418                final int NP = mProcessNames.getMap().size();
5419                for (int ip=0; ip<NP; ip++) {
5420                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5421                    final int NA = apps.size();
5422                    for (int ia=0; ia<NA; ia++) {
5423                        ProcessRecord app = apps.valueAt(ia);
5424                        if (app.persistent) {
5425                            // we don't kill persistent processes
5426                            continue;
5427                        }
5428                        if (app.removed) {
5429                            procs.add(app);
5430                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5431                            app.removed = true;
5432                            procs.add(app);
5433                        }
5434                    }
5435                }
5436
5437                int N = procs.size();
5438                for (int i=0; i<N; i++) {
5439                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5440                }
5441                mAllowLowerMemLevel = true;
5442                updateOomAdjLocked();
5443                doLowMemReportIfNeededLocked(null);
5444            }
5445        } finally {
5446            Binder.restoreCallingIdentity(callingId);
5447        }
5448    }
5449
5450    @Override
5451    public void forceStopPackage(final String packageName, int userId) {
5452        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5453                != PackageManager.PERMISSION_GRANTED) {
5454            String msg = "Permission Denial: forceStopPackage() from pid="
5455                    + Binder.getCallingPid()
5456                    + ", uid=" + Binder.getCallingUid()
5457                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5458            Slog.w(TAG, msg);
5459            throw new SecurityException(msg);
5460        }
5461        final int callingPid = Binder.getCallingPid();
5462        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5463                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5464        long callingId = Binder.clearCallingIdentity();
5465        try {
5466            IPackageManager pm = AppGlobals.getPackageManager();
5467            synchronized(this) {
5468                int[] users = userId == UserHandle.USER_ALL
5469                        ? getUsersLocked() : new int[] { userId };
5470                for (int user : users) {
5471                    int pkgUid = -1;
5472                    try {
5473                        pkgUid = pm.getPackageUid(packageName, user);
5474                    } catch (RemoteException e) {
5475                    }
5476                    if (pkgUid == -1) {
5477                        Slog.w(TAG, "Invalid packageName: " + packageName);
5478                        continue;
5479                    }
5480                    try {
5481                        pm.setPackageStoppedState(packageName, true, user);
5482                    } catch (RemoteException e) {
5483                    } catch (IllegalArgumentException e) {
5484                        Slog.w(TAG, "Failed trying to unstop package "
5485                                + packageName + ": " + e);
5486                    }
5487                    if (isUserRunningLocked(user, false)) {
5488                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5489                    }
5490                }
5491            }
5492        } finally {
5493            Binder.restoreCallingIdentity(callingId);
5494        }
5495    }
5496
5497    @Override
5498    public void addPackageDependency(String packageName) {
5499        synchronized (this) {
5500            int callingPid = Binder.getCallingPid();
5501            if (callingPid == Process.myPid()) {
5502                //  Yeah, um, no.
5503                Slog.w(TAG, "Can't addPackageDependency on system process");
5504                return;
5505            }
5506            ProcessRecord proc;
5507            synchronized (mPidsSelfLocked) {
5508                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5509            }
5510            if (proc != null) {
5511                if (proc.pkgDeps == null) {
5512                    proc.pkgDeps = new ArraySet<String>(1);
5513                }
5514                proc.pkgDeps.add(packageName);
5515            }
5516        }
5517    }
5518
5519    /*
5520     * The pkg name and app id have to be specified.
5521     */
5522    @Override
5523    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5524        if (pkg == null) {
5525            return;
5526        }
5527        // Make sure the uid is valid.
5528        if (appid < 0) {
5529            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5530            return;
5531        }
5532        int callerUid = Binder.getCallingUid();
5533        // Only the system server can kill an application
5534        if (callerUid == Process.SYSTEM_UID) {
5535            // Post an aysnc message to kill the application
5536            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5537            msg.arg1 = appid;
5538            msg.arg2 = 0;
5539            Bundle bundle = new Bundle();
5540            bundle.putString("pkg", pkg);
5541            bundle.putString("reason", reason);
5542            msg.obj = bundle;
5543            mHandler.sendMessage(msg);
5544        } else {
5545            throw new SecurityException(callerUid + " cannot kill pkg: " +
5546                    pkg);
5547        }
5548    }
5549
5550    @Override
5551    public void closeSystemDialogs(String reason) {
5552        enforceNotIsolatedCaller("closeSystemDialogs");
5553
5554        final int pid = Binder.getCallingPid();
5555        final int uid = Binder.getCallingUid();
5556        final long origId = Binder.clearCallingIdentity();
5557        try {
5558            synchronized (this) {
5559                // Only allow this from foreground processes, so that background
5560                // applications can't abuse it to prevent system UI from being shown.
5561                if (uid >= Process.FIRST_APPLICATION_UID) {
5562                    ProcessRecord proc;
5563                    synchronized (mPidsSelfLocked) {
5564                        proc = mPidsSelfLocked.get(pid);
5565                    }
5566                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5567                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5568                                + " from background process " + proc);
5569                        return;
5570                    }
5571                }
5572                closeSystemDialogsLocked(reason);
5573            }
5574        } finally {
5575            Binder.restoreCallingIdentity(origId);
5576        }
5577    }
5578
5579    void closeSystemDialogsLocked(String reason) {
5580        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5581        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5582                | Intent.FLAG_RECEIVER_FOREGROUND);
5583        if (reason != null) {
5584            intent.putExtra("reason", reason);
5585        }
5586        mWindowManager.closeSystemDialogs(reason);
5587
5588        mStackSupervisor.closeSystemDialogsLocked();
5589
5590        broadcastIntentLocked(null, null, intent, null,
5591                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5592                Process.SYSTEM_UID, UserHandle.USER_ALL);
5593    }
5594
5595    @Override
5596    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5597        enforceNotIsolatedCaller("getProcessMemoryInfo");
5598        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5599        for (int i=pids.length-1; i>=0; i--) {
5600            ProcessRecord proc;
5601            int oomAdj;
5602            synchronized (this) {
5603                synchronized (mPidsSelfLocked) {
5604                    proc = mPidsSelfLocked.get(pids[i]);
5605                    oomAdj = proc != null ? proc.setAdj : 0;
5606                }
5607            }
5608            infos[i] = new Debug.MemoryInfo();
5609            Debug.getMemoryInfo(pids[i], infos[i]);
5610            if (proc != null) {
5611                synchronized (this) {
5612                    if (proc.thread != null && proc.setAdj == oomAdj) {
5613                        // Record this for posterity if the process has been stable.
5614                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5615                                infos[i].getTotalUss(), false, proc.pkgList);
5616                    }
5617                }
5618            }
5619        }
5620        return infos;
5621    }
5622
5623    @Override
5624    public long[] getProcessPss(int[] pids) {
5625        enforceNotIsolatedCaller("getProcessPss");
5626        long[] pss = new long[pids.length];
5627        for (int i=pids.length-1; i>=0; i--) {
5628            ProcessRecord proc;
5629            int oomAdj;
5630            synchronized (this) {
5631                synchronized (mPidsSelfLocked) {
5632                    proc = mPidsSelfLocked.get(pids[i]);
5633                    oomAdj = proc != null ? proc.setAdj : 0;
5634                }
5635            }
5636            long[] tmpUss = new long[1];
5637            pss[i] = Debug.getPss(pids[i], tmpUss);
5638            if (proc != null) {
5639                synchronized (this) {
5640                    if (proc.thread != null && proc.setAdj == oomAdj) {
5641                        // Record this for posterity if the process has been stable.
5642                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5643                    }
5644                }
5645            }
5646        }
5647        return pss;
5648    }
5649
5650    @Override
5651    public void killApplicationProcess(String processName, int uid) {
5652        if (processName == null) {
5653            return;
5654        }
5655
5656        int callerUid = Binder.getCallingUid();
5657        // Only the system server can kill an application
5658        if (callerUid == Process.SYSTEM_UID) {
5659            synchronized (this) {
5660                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5661                if (app != null && app.thread != null) {
5662                    try {
5663                        app.thread.scheduleSuicide();
5664                    } catch (RemoteException e) {
5665                        // If the other end already died, then our work here is done.
5666                    }
5667                } else {
5668                    Slog.w(TAG, "Process/uid not found attempting kill of "
5669                            + processName + " / " + uid);
5670                }
5671            }
5672        } else {
5673            throw new SecurityException(callerUid + " cannot kill app process: " +
5674                    processName);
5675        }
5676    }
5677
5678    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5679        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5680                false, true, false, false, UserHandle.getUserId(uid), reason);
5681        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5682                Uri.fromParts("package", packageName, null));
5683        if (!mProcessesReady) {
5684            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5685                    | Intent.FLAG_RECEIVER_FOREGROUND);
5686        }
5687        intent.putExtra(Intent.EXTRA_UID, uid);
5688        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5689        broadcastIntentLocked(null, null, intent,
5690                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5691                false, false,
5692                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5693    }
5694
5695    private void forceStopUserLocked(int userId, String reason) {
5696        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5697        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5698        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5699                | Intent.FLAG_RECEIVER_FOREGROUND);
5700        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5701        broadcastIntentLocked(null, null, intent,
5702                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5703                false, false,
5704                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5705    }
5706
5707    private final boolean killPackageProcessesLocked(String packageName, int appId,
5708            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5709            boolean doit, boolean evenPersistent, String reason) {
5710        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5711
5712        // Remove all processes this package may have touched: all with the
5713        // same UID (except for the system or root user), and all whose name
5714        // matches the package name.
5715        final int NP = mProcessNames.getMap().size();
5716        for (int ip=0; ip<NP; ip++) {
5717            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5718            final int NA = apps.size();
5719            for (int ia=0; ia<NA; ia++) {
5720                ProcessRecord app = apps.valueAt(ia);
5721                if (app.persistent && !evenPersistent) {
5722                    // we don't kill persistent processes
5723                    continue;
5724                }
5725                if (app.removed) {
5726                    if (doit) {
5727                        procs.add(app);
5728                    }
5729                    continue;
5730                }
5731
5732                // Skip process if it doesn't meet our oom adj requirement.
5733                if (app.setAdj < minOomAdj) {
5734                    continue;
5735                }
5736
5737                // If no package is specified, we call all processes under the
5738                // give user id.
5739                if (packageName == null) {
5740                    if (app.userId != userId) {
5741                        continue;
5742                    }
5743                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5744                        continue;
5745                    }
5746                // Package has been specified, we want to hit all processes
5747                // that match it.  We need to qualify this by the processes
5748                // that are running under the specified app and user ID.
5749                } else {
5750                    final boolean isDep = app.pkgDeps != null
5751                            && app.pkgDeps.contains(packageName);
5752                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5753                        continue;
5754                    }
5755                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5756                        continue;
5757                    }
5758                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5759                        continue;
5760                    }
5761                }
5762
5763                // Process has passed all conditions, kill it!
5764                if (!doit) {
5765                    return true;
5766                }
5767                app.removed = true;
5768                procs.add(app);
5769            }
5770        }
5771
5772        int N = procs.size();
5773        for (int i=0; i<N; i++) {
5774            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5775        }
5776        updateOomAdjLocked();
5777        return N > 0;
5778    }
5779
5780    private final boolean forceStopPackageLocked(String name, int appId,
5781            boolean callerWillRestart, boolean purgeCache, boolean doit,
5782            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5783        int i;
5784        int N;
5785
5786        if (userId == UserHandle.USER_ALL && name == null) {
5787            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5788        }
5789
5790        if (appId < 0 && name != null) {
5791            try {
5792                appId = UserHandle.getAppId(
5793                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5794            } catch (RemoteException e) {
5795            }
5796        }
5797
5798        if (doit) {
5799            if (name != null) {
5800                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5801                        + " user=" + userId + ": " + reason);
5802            } else {
5803                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5804            }
5805
5806            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5807            for (int ip=pmap.size()-1; ip>=0; ip--) {
5808                SparseArray<Long> ba = pmap.valueAt(ip);
5809                for (i=ba.size()-1; i>=0; i--) {
5810                    boolean remove = false;
5811                    final int entUid = ba.keyAt(i);
5812                    if (name != null) {
5813                        if (userId == UserHandle.USER_ALL) {
5814                            if (UserHandle.getAppId(entUid) == appId) {
5815                                remove = true;
5816                            }
5817                        } else {
5818                            if (entUid == UserHandle.getUid(userId, appId)) {
5819                                remove = true;
5820                            }
5821                        }
5822                    } else if (UserHandle.getUserId(entUid) == userId) {
5823                        remove = true;
5824                    }
5825                    if (remove) {
5826                        ba.removeAt(i);
5827                    }
5828                }
5829                if (ba.size() == 0) {
5830                    pmap.removeAt(ip);
5831                }
5832            }
5833        }
5834
5835        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5836                -100, callerWillRestart, true, doit, evenPersistent,
5837                name == null ? ("stop user " + userId) : ("stop " + name));
5838
5839        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5840            if (!doit) {
5841                return true;
5842            }
5843            didSomething = true;
5844        }
5845
5846        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5847            if (!doit) {
5848                return true;
5849            }
5850            didSomething = true;
5851        }
5852
5853        if (name == null) {
5854            // Remove all sticky broadcasts from this user.
5855            mStickyBroadcasts.remove(userId);
5856        }
5857
5858        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5859        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5860                userId, providers)) {
5861            if (!doit) {
5862                return true;
5863            }
5864            didSomething = true;
5865        }
5866        N = providers.size();
5867        for (i=0; i<N; i++) {
5868            removeDyingProviderLocked(null, providers.get(i), true);
5869        }
5870
5871        // Remove transient permissions granted from/to this package/user
5872        removeUriPermissionsForPackageLocked(name, userId, false);
5873
5874        if (name == null || uninstalling) {
5875            // Remove pending intents.  For now we only do this when force
5876            // stopping users, because we have some problems when doing this
5877            // for packages -- app widgets are not currently cleaned up for
5878            // such packages, so they can be left with bad pending intents.
5879            if (mIntentSenderRecords.size() > 0) {
5880                Iterator<WeakReference<PendingIntentRecord>> it
5881                        = mIntentSenderRecords.values().iterator();
5882                while (it.hasNext()) {
5883                    WeakReference<PendingIntentRecord> wpir = it.next();
5884                    if (wpir == null) {
5885                        it.remove();
5886                        continue;
5887                    }
5888                    PendingIntentRecord pir = wpir.get();
5889                    if (pir == null) {
5890                        it.remove();
5891                        continue;
5892                    }
5893                    if (name == null) {
5894                        // Stopping user, remove all objects for the user.
5895                        if (pir.key.userId != userId) {
5896                            // Not the same user, skip it.
5897                            continue;
5898                        }
5899                    } else {
5900                        if (UserHandle.getAppId(pir.uid) != appId) {
5901                            // Different app id, skip it.
5902                            continue;
5903                        }
5904                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5905                            // Different user, skip it.
5906                            continue;
5907                        }
5908                        if (!pir.key.packageName.equals(name)) {
5909                            // Different package, skip it.
5910                            continue;
5911                        }
5912                    }
5913                    if (!doit) {
5914                        return true;
5915                    }
5916                    didSomething = true;
5917                    it.remove();
5918                    pir.canceled = true;
5919                    if (pir.key.activity != null) {
5920                        pir.key.activity.pendingResults.remove(pir.ref);
5921                    }
5922                }
5923            }
5924        }
5925
5926        if (doit) {
5927            if (purgeCache && name != null) {
5928                AttributeCache ac = AttributeCache.instance();
5929                if (ac != null) {
5930                    ac.removePackage(name);
5931                }
5932            }
5933            if (mBooted) {
5934                mStackSupervisor.resumeTopActivitiesLocked();
5935                mStackSupervisor.scheduleIdleLocked();
5936            }
5937        }
5938
5939        return didSomething;
5940    }
5941
5942    private final boolean removeProcessLocked(ProcessRecord app,
5943            boolean callerWillRestart, boolean allowRestart, String reason) {
5944        final String name = app.processName;
5945        final int uid = app.uid;
5946        if (DEBUG_PROCESSES) Slog.d(
5947            TAG, "Force removing proc " + app.toShortString() + " (" + name
5948            + "/" + uid + ")");
5949
5950        mProcessNames.remove(name, uid);
5951        mIsolatedProcesses.remove(app.uid);
5952        if (mHeavyWeightProcess == app) {
5953            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5954                    mHeavyWeightProcess.userId, 0));
5955            mHeavyWeightProcess = null;
5956        }
5957        boolean needRestart = false;
5958        if (app.pid > 0 && app.pid != MY_PID) {
5959            int pid = app.pid;
5960            synchronized (mPidsSelfLocked) {
5961                mPidsSelfLocked.remove(pid);
5962                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5963            }
5964            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5965            if (app.isolated) {
5966                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5967            }
5968            app.kill(reason, true);
5969            handleAppDiedLocked(app, true, allowRestart);
5970            removeLruProcessLocked(app);
5971
5972            if (app.persistent && !app.isolated) {
5973                if (!callerWillRestart) {
5974                    addAppLocked(app.info, false, null /* ABI override */);
5975                } else {
5976                    needRestart = true;
5977                }
5978            }
5979        } else {
5980            mRemovedProcesses.add(app);
5981        }
5982
5983        return needRestart;
5984    }
5985
5986    private final void processStartTimedOutLocked(ProcessRecord app) {
5987        final int pid = app.pid;
5988        boolean gone = false;
5989        synchronized (mPidsSelfLocked) {
5990            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5991            if (knownApp != null && knownApp.thread == null) {
5992                mPidsSelfLocked.remove(pid);
5993                gone = true;
5994            }
5995        }
5996
5997        if (gone) {
5998            Slog.w(TAG, "Process " + app + " failed to attach");
5999            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6000                    pid, app.uid, app.processName);
6001            mProcessNames.remove(app.processName, app.uid);
6002            mIsolatedProcesses.remove(app.uid);
6003            if (mHeavyWeightProcess == app) {
6004                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6005                        mHeavyWeightProcess.userId, 0));
6006                mHeavyWeightProcess = null;
6007            }
6008            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6009            if (app.isolated) {
6010                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6011            }
6012            // Take care of any launching providers waiting for this process.
6013            checkAppInLaunchingProvidersLocked(app, true);
6014            // Take care of any services that are waiting for the process.
6015            mServices.processStartTimedOutLocked(app);
6016            app.kill("start timeout", true);
6017            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6018                Slog.w(TAG, "Unattached app died before backup, skipping");
6019                try {
6020                    IBackupManager bm = IBackupManager.Stub.asInterface(
6021                            ServiceManager.getService(Context.BACKUP_SERVICE));
6022                    bm.agentDisconnected(app.info.packageName);
6023                } catch (RemoteException e) {
6024                    // Can't happen; the backup manager is local
6025                }
6026            }
6027            if (isPendingBroadcastProcessLocked(pid)) {
6028                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6029                skipPendingBroadcastLocked(pid);
6030            }
6031        } else {
6032            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6033        }
6034    }
6035
6036    private final boolean attachApplicationLocked(IApplicationThread thread,
6037            int pid) {
6038
6039        // Find the application record that is being attached...  either via
6040        // the pid if we are running in multiple processes, or just pull the
6041        // next app record if we are emulating process with anonymous threads.
6042        ProcessRecord app;
6043        if (pid != MY_PID && pid >= 0) {
6044            synchronized (mPidsSelfLocked) {
6045                app = mPidsSelfLocked.get(pid);
6046            }
6047        } else {
6048            app = null;
6049        }
6050
6051        if (app == null) {
6052            Slog.w(TAG, "No pending application record for pid " + pid
6053                    + " (IApplicationThread " + thread + "); dropping process");
6054            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6055            if (pid > 0 && pid != MY_PID) {
6056                Process.killProcessQuiet(pid);
6057                //TODO: Process.killProcessGroup(app.info.uid, pid);
6058            } else {
6059                try {
6060                    thread.scheduleExit();
6061                } catch (Exception e) {
6062                    // Ignore exceptions.
6063                }
6064            }
6065            return false;
6066        }
6067
6068        // If this application record is still attached to a previous
6069        // process, clean it up now.
6070        if (app.thread != null) {
6071            handleAppDiedLocked(app, true, true);
6072        }
6073
6074        // Tell the process all about itself.
6075
6076        if (localLOGV) Slog.v(
6077                TAG, "Binding process pid " + pid + " to record " + app);
6078
6079        final String processName = app.processName;
6080        try {
6081            AppDeathRecipient adr = new AppDeathRecipient(
6082                    app, pid, thread);
6083            thread.asBinder().linkToDeath(adr, 0);
6084            app.deathRecipient = adr;
6085        } catch (RemoteException e) {
6086            app.resetPackageList(mProcessStats);
6087            startProcessLocked(app, "link fail", processName);
6088            return false;
6089        }
6090
6091        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6092
6093        app.makeActive(thread, mProcessStats);
6094        app.curAdj = app.setAdj = -100;
6095        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6096        app.forcingToForeground = null;
6097        updateProcessForegroundLocked(app, false, false);
6098        app.hasShownUi = false;
6099        app.debugging = false;
6100        app.cached = false;
6101
6102        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6103
6104        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6105        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6106
6107        if (!normalMode) {
6108            Slog.i(TAG, "Launching preboot mode app: " + app);
6109        }
6110
6111        if (localLOGV) Slog.v(
6112            TAG, "New app record " + app
6113            + " thread=" + thread.asBinder() + " pid=" + pid);
6114        try {
6115            int testMode = IApplicationThread.DEBUG_OFF;
6116            if (mDebugApp != null && mDebugApp.equals(processName)) {
6117                testMode = mWaitForDebugger
6118                    ? IApplicationThread.DEBUG_WAIT
6119                    : IApplicationThread.DEBUG_ON;
6120                app.debugging = true;
6121                if (mDebugTransient) {
6122                    mDebugApp = mOrigDebugApp;
6123                    mWaitForDebugger = mOrigWaitForDebugger;
6124                }
6125            }
6126            String profileFile = app.instrumentationProfileFile;
6127            ParcelFileDescriptor profileFd = null;
6128            int samplingInterval = 0;
6129            boolean profileAutoStop = false;
6130            if (mProfileApp != null && mProfileApp.equals(processName)) {
6131                mProfileProc = app;
6132                profileFile = mProfileFile;
6133                profileFd = mProfileFd;
6134                samplingInterval = mSamplingInterval;
6135                profileAutoStop = mAutoStopProfiler;
6136            }
6137            boolean enableOpenGlTrace = false;
6138            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6139                enableOpenGlTrace = true;
6140                mOpenGlTraceApp = null;
6141            }
6142
6143            // If the app is being launched for restore or full backup, set it up specially
6144            boolean isRestrictedBackupMode = false;
6145            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6146                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6147                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6148                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6149            }
6150
6151            ensurePackageDexOpt(app.instrumentationInfo != null
6152                    ? app.instrumentationInfo.packageName
6153                    : app.info.packageName);
6154            if (app.instrumentationClass != null) {
6155                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6156            }
6157            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6158                    + processName + " with config " + mConfiguration);
6159            ApplicationInfo appInfo = app.instrumentationInfo != null
6160                    ? app.instrumentationInfo : app.info;
6161            app.compat = compatibilityInfoForPackageLocked(appInfo);
6162            if (profileFd != null) {
6163                profileFd = profileFd.dup();
6164            }
6165            ProfilerInfo profilerInfo = profileFile == null ? null
6166                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6167            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6168                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6169                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6170                    isRestrictedBackupMode || !normalMode, app.persistent,
6171                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6172                    mCoreSettingsObserver.getCoreSettingsLocked());
6173            updateLruProcessLocked(app, false, null);
6174            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6175        } catch (Exception e) {
6176            // todo: Yikes!  What should we do?  For now we will try to
6177            // start another process, but that could easily get us in
6178            // an infinite loop of restarting processes...
6179            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6180
6181            app.resetPackageList(mProcessStats);
6182            app.unlinkDeathRecipient();
6183            startProcessLocked(app, "bind fail", processName);
6184            return false;
6185        }
6186
6187        // Remove this record from the list of starting applications.
6188        mPersistentStartingProcesses.remove(app);
6189        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6190                "Attach application locked removing on hold: " + app);
6191        mProcessesOnHold.remove(app);
6192
6193        boolean badApp = false;
6194        boolean didSomething = false;
6195
6196        // See if the top visible activity is waiting to run in this process...
6197        if (normalMode) {
6198            try {
6199                if (mStackSupervisor.attachApplicationLocked(app)) {
6200                    didSomething = true;
6201                }
6202            } catch (Exception e) {
6203                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6204                badApp = true;
6205            }
6206        }
6207
6208        // Find any services that should be running in this process...
6209        if (!badApp) {
6210            try {
6211                didSomething |= mServices.attachApplicationLocked(app, processName);
6212            } catch (Exception e) {
6213                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6214                badApp = true;
6215            }
6216        }
6217
6218        // Check if a next-broadcast receiver is in this process...
6219        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6220            try {
6221                didSomething |= sendPendingBroadcastsLocked(app);
6222            } catch (Exception e) {
6223                // If the app died trying to launch the receiver we declare it 'bad'
6224                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6225                badApp = true;
6226            }
6227        }
6228
6229        // Check whether the next backup agent is in this process...
6230        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6231            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6232            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6233            try {
6234                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6235                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6236                        mBackupTarget.backupMode);
6237            } catch (Exception e) {
6238                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6239                badApp = true;
6240            }
6241        }
6242
6243        if (badApp) {
6244            app.kill("error during init", true);
6245            handleAppDiedLocked(app, false, true);
6246            return false;
6247        }
6248
6249        if (!didSomething) {
6250            updateOomAdjLocked();
6251        }
6252
6253        return true;
6254    }
6255
6256    @Override
6257    public final void attachApplication(IApplicationThread thread) {
6258        synchronized (this) {
6259            int callingPid = Binder.getCallingPid();
6260            final long origId = Binder.clearCallingIdentity();
6261            attachApplicationLocked(thread, callingPid);
6262            Binder.restoreCallingIdentity(origId);
6263        }
6264    }
6265
6266    @Override
6267    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6268        final long origId = Binder.clearCallingIdentity();
6269        synchronized (this) {
6270            ActivityStack stack = ActivityRecord.getStackLocked(token);
6271            if (stack != null) {
6272                ActivityRecord r =
6273                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6274                if (stopProfiling) {
6275                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6276                        try {
6277                            mProfileFd.close();
6278                        } catch (IOException e) {
6279                        }
6280                        clearProfilerLocked();
6281                    }
6282                }
6283            }
6284        }
6285        Binder.restoreCallingIdentity(origId);
6286    }
6287
6288    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6289        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6290                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6291    }
6292
6293    void enableScreenAfterBoot() {
6294        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6295                SystemClock.uptimeMillis());
6296        mWindowManager.enableScreenAfterBoot();
6297
6298        synchronized (this) {
6299            updateEventDispatchingLocked();
6300        }
6301    }
6302
6303    @Override
6304    public void showBootMessage(final CharSequence msg, final boolean always) {
6305        enforceNotIsolatedCaller("showBootMessage");
6306        mWindowManager.showBootMessage(msg, always);
6307    }
6308
6309    @Override
6310    public void keyguardWaitingForActivityDrawn() {
6311        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6312        final long token = Binder.clearCallingIdentity();
6313        try {
6314            synchronized (this) {
6315                if (DEBUG_LOCKSCREEN) logLockScreen("");
6316                mWindowManager.keyguardWaitingForActivityDrawn();
6317                if (mLockScreenShown) {
6318                    mLockScreenShown = false;
6319                    comeOutOfSleepIfNeededLocked();
6320                }
6321            }
6322        } finally {
6323            Binder.restoreCallingIdentity(token);
6324        }
6325    }
6326
6327    final void finishBooting() {
6328        synchronized (this) {
6329            if (!mBootAnimationComplete) {
6330                mCallFinishBooting = true;
6331                return;
6332            }
6333            mCallFinishBooting = false;
6334        }
6335
6336        ArraySet<String> completedIsas = new ArraySet<String>();
6337        for (String abi : Build.SUPPORTED_ABIS) {
6338            Process.establishZygoteConnectionForAbi(abi);
6339            final String instructionSet = VMRuntime.getInstructionSet(abi);
6340            if (!completedIsas.contains(instructionSet)) {
6341                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6342                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6343                }
6344                completedIsas.add(instructionSet);
6345            }
6346        }
6347
6348        // Register receivers to handle package update events
6349        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6350
6351        // Let system services know.
6352        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6353
6354        synchronized (this) {
6355            // Ensure that any processes we had put on hold are now started
6356            // up.
6357            final int NP = mProcessesOnHold.size();
6358            if (NP > 0) {
6359                ArrayList<ProcessRecord> procs =
6360                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6361                for (int ip=0; ip<NP; ip++) {
6362                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6363                            + procs.get(ip));
6364                    startProcessLocked(procs.get(ip), "on-hold", null);
6365                }
6366            }
6367
6368            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6369                // Start looking for apps that are abusing wake locks.
6370                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6371                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6372                // Tell anyone interested that we are done booting!
6373                SystemProperties.set("sys.boot_completed", "1");
6374
6375                // And trigger dev.bootcomplete if we are not showing encryption progress
6376                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6377                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6378                    SystemProperties.set("dev.bootcomplete", "1");
6379                }
6380                for (int i=0; i<mStartedUsers.size(); i++) {
6381                    UserStartedState uss = mStartedUsers.valueAt(i);
6382                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6383                        uss.mState = UserStartedState.STATE_RUNNING;
6384                        final int userId = mStartedUsers.keyAt(i);
6385                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6386                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6387                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6388                        broadcastIntentLocked(null, null, intent, null,
6389                                new IIntentReceiver.Stub() {
6390                                    @Override
6391                                    public void performReceive(Intent intent, int resultCode,
6392                                            String data, Bundle extras, boolean ordered,
6393                                            boolean sticky, int sendingUser) {
6394                                        synchronized (ActivityManagerService.this) {
6395                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6396                                                    true, false);
6397                                        }
6398                                    }
6399                                },
6400                                0, null, null,
6401                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6402                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6403                                userId);
6404                    }
6405                }
6406                scheduleStartProfilesLocked();
6407            }
6408        }
6409    }
6410
6411    @Override
6412    public void bootAnimationComplete() {
6413        final boolean callFinishBooting;
6414        synchronized (this) {
6415            callFinishBooting = mCallFinishBooting;
6416            mBootAnimationComplete = true;
6417        }
6418        if (callFinishBooting) {
6419            finishBooting();
6420        }
6421    }
6422
6423    final void ensureBootCompleted() {
6424        boolean booting;
6425        boolean enableScreen;
6426        synchronized (this) {
6427            booting = mBooting;
6428            mBooting = false;
6429            enableScreen = !mBooted;
6430            mBooted = true;
6431        }
6432
6433        if (booting) {
6434            finishBooting();
6435        }
6436
6437        if (enableScreen) {
6438            enableScreenAfterBoot();
6439        }
6440    }
6441
6442    @Override
6443    public final void activityResumed(IBinder token) {
6444        final long origId = Binder.clearCallingIdentity();
6445        synchronized(this) {
6446            ActivityStack stack = ActivityRecord.getStackLocked(token);
6447            if (stack != null) {
6448                ActivityRecord.activityResumedLocked(token);
6449            }
6450        }
6451        Binder.restoreCallingIdentity(origId);
6452    }
6453
6454    @Override
6455    public final void activityPaused(IBinder token) {
6456        final long origId = Binder.clearCallingIdentity();
6457        synchronized(this) {
6458            ActivityStack stack = ActivityRecord.getStackLocked(token);
6459            if (stack != null) {
6460                stack.activityPausedLocked(token, false);
6461            }
6462        }
6463        Binder.restoreCallingIdentity(origId);
6464    }
6465
6466    @Override
6467    public final void activityStopped(IBinder token, Bundle icicle,
6468            PersistableBundle persistentState, CharSequence description) {
6469        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6470
6471        // Refuse possible leaked file descriptors
6472        if (icicle != null && icicle.hasFileDescriptors()) {
6473            throw new IllegalArgumentException("File descriptors passed in Bundle");
6474        }
6475
6476        final long origId = Binder.clearCallingIdentity();
6477
6478        synchronized (this) {
6479            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6480            if (r != null) {
6481                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6482            }
6483        }
6484
6485        trimApplications();
6486
6487        Binder.restoreCallingIdentity(origId);
6488    }
6489
6490    @Override
6491    public final void activityDestroyed(IBinder token) {
6492        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6493        synchronized (this) {
6494            ActivityStack stack = ActivityRecord.getStackLocked(token);
6495            if (stack != null) {
6496                stack.activityDestroyedLocked(token);
6497            }
6498        }
6499    }
6500
6501    @Override
6502    public final void backgroundResourcesReleased(IBinder token) {
6503        final long origId = Binder.clearCallingIdentity();
6504        try {
6505            synchronized (this) {
6506                ActivityStack stack = ActivityRecord.getStackLocked(token);
6507                if (stack != null) {
6508                    stack.backgroundResourcesReleased(token);
6509                }
6510            }
6511        } finally {
6512            Binder.restoreCallingIdentity(origId);
6513        }
6514    }
6515
6516    @Override
6517    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6518        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6519    }
6520
6521    @Override
6522    public final void notifyEnterAnimationComplete(IBinder token) {
6523        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6524    }
6525
6526    @Override
6527    public String getCallingPackage(IBinder token) {
6528        synchronized (this) {
6529            ActivityRecord r = getCallingRecordLocked(token);
6530            return r != null ? r.info.packageName : null;
6531        }
6532    }
6533
6534    @Override
6535    public ComponentName getCallingActivity(IBinder token) {
6536        synchronized (this) {
6537            ActivityRecord r = getCallingRecordLocked(token);
6538            return r != null ? r.intent.getComponent() : null;
6539        }
6540    }
6541
6542    private ActivityRecord getCallingRecordLocked(IBinder token) {
6543        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6544        if (r == null) {
6545            return null;
6546        }
6547        return r.resultTo;
6548    }
6549
6550    @Override
6551    public ComponentName getActivityClassForToken(IBinder token) {
6552        synchronized(this) {
6553            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6554            if (r == null) {
6555                return null;
6556            }
6557            return r.intent.getComponent();
6558        }
6559    }
6560
6561    @Override
6562    public String getPackageForToken(IBinder token) {
6563        synchronized(this) {
6564            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6565            if (r == null) {
6566                return null;
6567            }
6568            return r.packageName;
6569        }
6570    }
6571
6572    @Override
6573    public IIntentSender getIntentSender(int type,
6574            String packageName, IBinder token, String resultWho,
6575            int requestCode, Intent[] intents, String[] resolvedTypes,
6576            int flags, Bundle options, int userId) {
6577        enforceNotIsolatedCaller("getIntentSender");
6578        // Refuse possible leaked file descriptors
6579        if (intents != null) {
6580            if (intents.length < 1) {
6581                throw new IllegalArgumentException("Intents array length must be >= 1");
6582            }
6583            for (int i=0; i<intents.length; i++) {
6584                Intent intent = intents[i];
6585                if (intent != null) {
6586                    if (intent.hasFileDescriptors()) {
6587                        throw new IllegalArgumentException("File descriptors passed in Intent");
6588                    }
6589                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6590                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6591                        throw new IllegalArgumentException(
6592                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6593                    }
6594                    intents[i] = new Intent(intent);
6595                }
6596            }
6597            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6598                throw new IllegalArgumentException(
6599                        "Intent array length does not match resolvedTypes length");
6600            }
6601        }
6602        if (options != null) {
6603            if (options.hasFileDescriptors()) {
6604                throw new IllegalArgumentException("File descriptors passed in options");
6605            }
6606        }
6607
6608        synchronized(this) {
6609            int callingUid = Binder.getCallingUid();
6610            int origUserId = userId;
6611            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6612                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6613                    ALLOW_NON_FULL, "getIntentSender", null);
6614            if (origUserId == UserHandle.USER_CURRENT) {
6615                // We don't want to evaluate this until the pending intent is
6616                // actually executed.  However, we do want to always do the
6617                // security checking for it above.
6618                userId = UserHandle.USER_CURRENT;
6619            }
6620            try {
6621                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6622                    int uid = AppGlobals.getPackageManager()
6623                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6624                    if (!UserHandle.isSameApp(callingUid, uid)) {
6625                        String msg = "Permission Denial: getIntentSender() from pid="
6626                            + Binder.getCallingPid()
6627                            + ", uid=" + Binder.getCallingUid()
6628                            + ", (need uid=" + uid + ")"
6629                            + " is not allowed to send as package " + packageName;
6630                        Slog.w(TAG, msg);
6631                        throw new SecurityException(msg);
6632                    }
6633                }
6634
6635                return getIntentSenderLocked(type, packageName, callingUid, userId,
6636                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6637
6638            } catch (RemoteException e) {
6639                throw new SecurityException(e);
6640            }
6641        }
6642    }
6643
6644    IIntentSender getIntentSenderLocked(int type, String packageName,
6645            int callingUid, int userId, IBinder token, String resultWho,
6646            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6647            Bundle options) {
6648        if (DEBUG_MU)
6649            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6650        ActivityRecord activity = null;
6651        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6652            activity = ActivityRecord.isInStackLocked(token);
6653            if (activity == null) {
6654                return null;
6655            }
6656            if (activity.finishing) {
6657                return null;
6658            }
6659        }
6660
6661        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6662        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6663        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6664        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6665                |PendingIntent.FLAG_UPDATE_CURRENT);
6666
6667        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6668                type, packageName, activity, resultWho,
6669                requestCode, intents, resolvedTypes, flags, options, userId);
6670        WeakReference<PendingIntentRecord> ref;
6671        ref = mIntentSenderRecords.get(key);
6672        PendingIntentRecord rec = ref != null ? ref.get() : null;
6673        if (rec != null) {
6674            if (!cancelCurrent) {
6675                if (updateCurrent) {
6676                    if (rec.key.requestIntent != null) {
6677                        rec.key.requestIntent.replaceExtras(intents != null ?
6678                                intents[intents.length - 1] : null);
6679                    }
6680                    if (intents != null) {
6681                        intents[intents.length-1] = rec.key.requestIntent;
6682                        rec.key.allIntents = intents;
6683                        rec.key.allResolvedTypes = resolvedTypes;
6684                    } else {
6685                        rec.key.allIntents = null;
6686                        rec.key.allResolvedTypes = null;
6687                    }
6688                }
6689                return rec;
6690            }
6691            rec.canceled = true;
6692            mIntentSenderRecords.remove(key);
6693        }
6694        if (noCreate) {
6695            return rec;
6696        }
6697        rec = new PendingIntentRecord(this, key, callingUid);
6698        mIntentSenderRecords.put(key, rec.ref);
6699        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6700            if (activity.pendingResults == null) {
6701                activity.pendingResults
6702                        = new HashSet<WeakReference<PendingIntentRecord>>();
6703            }
6704            activity.pendingResults.add(rec.ref);
6705        }
6706        return rec;
6707    }
6708
6709    @Override
6710    public void cancelIntentSender(IIntentSender sender) {
6711        if (!(sender instanceof PendingIntentRecord)) {
6712            return;
6713        }
6714        synchronized(this) {
6715            PendingIntentRecord rec = (PendingIntentRecord)sender;
6716            try {
6717                int uid = AppGlobals.getPackageManager()
6718                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6719                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6720                    String msg = "Permission Denial: cancelIntentSender() from pid="
6721                        + Binder.getCallingPid()
6722                        + ", uid=" + Binder.getCallingUid()
6723                        + " is not allowed to cancel packges "
6724                        + rec.key.packageName;
6725                    Slog.w(TAG, msg);
6726                    throw new SecurityException(msg);
6727                }
6728            } catch (RemoteException e) {
6729                throw new SecurityException(e);
6730            }
6731            cancelIntentSenderLocked(rec, true);
6732        }
6733    }
6734
6735    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6736        rec.canceled = true;
6737        mIntentSenderRecords.remove(rec.key);
6738        if (cleanActivity && rec.key.activity != null) {
6739            rec.key.activity.pendingResults.remove(rec.ref);
6740        }
6741    }
6742
6743    @Override
6744    public String getPackageForIntentSender(IIntentSender pendingResult) {
6745        if (!(pendingResult instanceof PendingIntentRecord)) {
6746            return null;
6747        }
6748        try {
6749            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6750            return res.key.packageName;
6751        } catch (ClassCastException e) {
6752        }
6753        return null;
6754    }
6755
6756    @Override
6757    public int getUidForIntentSender(IIntentSender sender) {
6758        if (sender instanceof PendingIntentRecord) {
6759            try {
6760                PendingIntentRecord res = (PendingIntentRecord)sender;
6761                return res.uid;
6762            } catch (ClassCastException e) {
6763            }
6764        }
6765        return -1;
6766    }
6767
6768    @Override
6769    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6770        if (!(pendingResult instanceof PendingIntentRecord)) {
6771            return false;
6772        }
6773        try {
6774            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6775            if (res.key.allIntents == null) {
6776                return false;
6777            }
6778            for (int i=0; i<res.key.allIntents.length; i++) {
6779                Intent intent = res.key.allIntents[i];
6780                if (intent.getPackage() != null && intent.getComponent() != null) {
6781                    return false;
6782                }
6783            }
6784            return true;
6785        } catch (ClassCastException e) {
6786        }
6787        return false;
6788    }
6789
6790    @Override
6791    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6792        if (!(pendingResult instanceof PendingIntentRecord)) {
6793            return false;
6794        }
6795        try {
6796            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6797            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6798                return true;
6799            }
6800            return false;
6801        } catch (ClassCastException e) {
6802        }
6803        return false;
6804    }
6805
6806    @Override
6807    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6808        if (!(pendingResult instanceof PendingIntentRecord)) {
6809            return null;
6810        }
6811        try {
6812            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6813            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6814        } catch (ClassCastException e) {
6815        }
6816        return null;
6817    }
6818
6819    @Override
6820    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6821        if (!(pendingResult instanceof PendingIntentRecord)) {
6822            return null;
6823        }
6824        try {
6825            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6826            Intent intent = res.key.requestIntent;
6827            if (intent != null) {
6828                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6829                        || res.lastTagPrefix.equals(prefix))) {
6830                    return res.lastTag;
6831                }
6832                res.lastTagPrefix = prefix;
6833                StringBuilder sb = new StringBuilder(128);
6834                if (prefix != null) {
6835                    sb.append(prefix);
6836                }
6837                if (intent.getAction() != null) {
6838                    sb.append(intent.getAction());
6839                } else if (intent.getComponent() != null) {
6840                    intent.getComponent().appendShortString(sb);
6841                } else {
6842                    sb.append("?");
6843                }
6844                return res.lastTag = sb.toString();
6845            }
6846        } catch (ClassCastException e) {
6847        }
6848        return null;
6849    }
6850
6851    @Override
6852    public void setProcessLimit(int max) {
6853        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6854                "setProcessLimit()");
6855        synchronized (this) {
6856            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6857            mProcessLimitOverride = max;
6858        }
6859        trimApplications();
6860    }
6861
6862    @Override
6863    public int getProcessLimit() {
6864        synchronized (this) {
6865            return mProcessLimitOverride;
6866        }
6867    }
6868
6869    void foregroundTokenDied(ForegroundToken token) {
6870        synchronized (ActivityManagerService.this) {
6871            synchronized (mPidsSelfLocked) {
6872                ForegroundToken cur
6873                    = mForegroundProcesses.get(token.pid);
6874                if (cur != token) {
6875                    return;
6876                }
6877                mForegroundProcesses.remove(token.pid);
6878                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6879                if (pr == null) {
6880                    return;
6881                }
6882                pr.forcingToForeground = null;
6883                updateProcessForegroundLocked(pr, false, false);
6884            }
6885            updateOomAdjLocked();
6886        }
6887    }
6888
6889    @Override
6890    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6891        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6892                "setProcessForeground()");
6893        synchronized(this) {
6894            boolean changed = false;
6895
6896            synchronized (mPidsSelfLocked) {
6897                ProcessRecord pr = mPidsSelfLocked.get(pid);
6898                if (pr == null && isForeground) {
6899                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6900                    return;
6901                }
6902                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6903                if (oldToken != null) {
6904                    oldToken.token.unlinkToDeath(oldToken, 0);
6905                    mForegroundProcesses.remove(pid);
6906                    if (pr != null) {
6907                        pr.forcingToForeground = null;
6908                    }
6909                    changed = true;
6910                }
6911                if (isForeground && token != null) {
6912                    ForegroundToken newToken = new ForegroundToken() {
6913                        @Override
6914                        public void binderDied() {
6915                            foregroundTokenDied(this);
6916                        }
6917                    };
6918                    newToken.pid = pid;
6919                    newToken.token = token;
6920                    try {
6921                        token.linkToDeath(newToken, 0);
6922                        mForegroundProcesses.put(pid, newToken);
6923                        pr.forcingToForeground = token;
6924                        changed = true;
6925                    } catch (RemoteException e) {
6926                        // If the process died while doing this, we will later
6927                        // do the cleanup with the process death link.
6928                    }
6929                }
6930            }
6931
6932            if (changed) {
6933                updateOomAdjLocked();
6934            }
6935        }
6936    }
6937
6938    // =========================================================
6939    // PERMISSIONS
6940    // =========================================================
6941
6942    static class PermissionController extends IPermissionController.Stub {
6943        ActivityManagerService mActivityManagerService;
6944        PermissionController(ActivityManagerService activityManagerService) {
6945            mActivityManagerService = activityManagerService;
6946        }
6947
6948        @Override
6949        public boolean checkPermission(String permission, int pid, int uid) {
6950            return mActivityManagerService.checkPermission(permission, pid,
6951                    uid) == PackageManager.PERMISSION_GRANTED;
6952        }
6953    }
6954
6955    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6956        @Override
6957        public int checkComponentPermission(String permission, int pid, int uid,
6958                int owningUid, boolean exported) {
6959            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6960                    owningUid, exported);
6961        }
6962
6963        @Override
6964        public Object getAMSLock() {
6965            return ActivityManagerService.this;
6966        }
6967    }
6968
6969    /**
6970     * This can be called with or without the global lock held.
6971     */
6972    int checkComponentPermission(String permission, int pid, int uid,
6973            int owningUid, boolean exported) {
6974        // We might be performing an operation on behalf of an indirect binder
6975        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6976        // client identity accordingly before proceeding.
6977        Identity tlsIdentity = sCallerIdentity.get();
6978        if (tlsIdentity != null) {
6979            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6980                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6981            uid = tlsIdentity.uid;
6982            pid = tlsIdentity.pid;
6983        }
6984
6985        if (pid == MY_PID) {
6986            return PackageManager.PERMISSION_GRANTED;
6987        }
6988
6989        return ActivityManager.checkComponentPermission(permission, uid,
6990                owningUid, exported);
6991    }
6992
6993    /**
6994     * As the only public entry point for permissions checking, this method
6995     * can enforce the semantic that requesting a check on a null global
6996     * permission is automatically denied.  (Internally a null permission
6997     * string is used when calling {@link #checkComponentPermission} in cases
6998     * when only uid-based security is needed.)
6999     *
7000     * This can be called with or without the global lock held.
7001     */
7002    @Override
7003    public int checkPermission(String permission, int pid, int uid) {
7004        if (permission == null) {
7005            return PackageManager.PERMISSION_DENIED;
7006        }
7007        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
7008    }
7009
7010    /**
7011     * Binder IPC calls go through the public entry point.
7012     * This can be called with or without the global lock held.
7013     */
7014    int checkCallingPermission(String permission) {
7015        return checkPermission(permission,
7016                Binder.getCallingPid(),
7017                UserHandle.getAppId(Binder.getCallingUid()));
7018    }
7019
7020    /**
7021     * This can be called with or without the global lock held.
7022     */
7023    void enforceCallingPermission(String permission, String func) {
7024        if (checkCallingPermission(permission)
7025                == PackageManager.PERMISSION_GRANTED) {
7026            return;
7027        }
7028
7029        String msg = "Permission Denial: " + func + " from pid="
7030                + Binder.getCallingPid()
7031                + ", uid=" + Binder.getCallingUid()
7032                + " requires " + permission;
7033        Slog.w(TAG, msg);
7034        throw new SecurityException(msg);
7035    }
7036
7037    /**
7038     * Determine if UID is holding permissions required to access {@link Uri} in
7039     * the given {@link ProviderInfo}. Final permission checking is always done
7040     * in {@link ContentProvider}.
7041     */
7042    private final boolean checkHoldingPermissionsLocked(
7043            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7044        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7045                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7046        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7047            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7048                    != PERMISSION_GRANTED) {
7049                return false;
7050            }
7051        }
7052        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7053    }
7054
7055    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7056            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7057        if (pi.applicationInfo.uid == uid) {
7058            return true;
7059        } else if (!pi.exported) {
7060            return false;
7061        }
7062
7063        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7064        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7065        try {
7066            // check if target holds top-level <provider> permissions
7067            if (!readMet && pi.readPermission != null && considerUidPermissions
7068                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7069                readMet = true;
7070            }
7071            if (!writeMet && pi.writePermission != null && considerUidPermissions
7072                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7073                writeMet = true;
7074            }
7075
7076            // track if unprotected read/write is allowed; any denied
7077            // <path-permission> below removes this ability
7078            boolean allowDefaultRead = pi.readPermission == null;
7079            boolean allowDefaultWrite = pi.writePermission == null;
7080
7081            // check if target holds any <path-permission> that match uri
7082            final PathPermission[] pps = pi.pathPermissions;
7083            if (pps != null) {
7084                final String path = grantUri.uri.getPath();
7085                int i = pps.length;
7086                while (i > 0 && (!readMet || !writeMet)) {
7087                    i--;
7088                    PathPermission pp = pps[i];
7089                    if (pp.match(path)) {
7090                        if (!readMet) {
7091                            final String pprperm = pp.getReadPermission();
7092                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7093                                    + pprperm + " for " + pp.getPath()
7094                                    + ": match=" + pp.match(path)
7095                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7096                            if (pprperm != null) {
7097                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7098                                        == PERMISSION_GRANTED) {
7099                                    readMet = true;
7100                                } else {
7101                                    allowDefaultRead = false;
7102                                }
7103                            }
7104                        }
7105                        if (!writeMet) {
7106                            final String ppwperm = pp.getWritePermission();
7107                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7108                                    + ppwperm + " for " + pp.getPath()
7109                                    + ": match=" + pp.match(path)
7110                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7111                            if (ppwperm != null) {
7112                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7113                                        == PERMISSION_GRANTED) {
7114                                    writeMet = true;
7115                                } else {
7116                                    allowDefaultWrite = false;
7117                                }
7118                            }
7119                        }
7120                    }
7121                }
7122            }
7123
7124            // grant unprotected <provider> read/write, if not blocked by
7125            // <path-permission> above
7126            if (allowDefaultRead) readMet = true;
7127            if (allowDefaultWrite) writeMet = true;
7128
7129        } catch (RemoteException e) {
7130            return false;
7131        }
7132
7133        return readMet && writeMet;
7134    }
7135
7136    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7137        ProviderInfo pi = null;
7138        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7139        if (cpr != null) {
7140            pi = cpr.info;
7141        } else {
7142            try {
7143                pi = AppGlobals.getPackageManager().resolveContentProvider(
7144                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7145            } catch (RemoteException ex) {
7146            }
7147        }
7148        return pi;
7149    }
7150
7151    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7152        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7153        if (targetUris != null) {
7154            return targetUris.get(grantUri);
7155        }
7156        return null;
7157    }
7158
7159    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7160            String targetPkg, int targetUid, GrantUri grantUri) {
7161        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7162        if (targetUris == null) {
7163            targetUris = Maps.newArrayMap();
7164            mGrantedUriPermissions.put(targetUid, targetUris);
7165        }
7166
7167        UriPermission perm = targetUris.get(grantUri);
7168        if (perm == null) {
7169            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7170            targetUris.put(grantUri, perm);
7171        }
7172
7173        return perm;
7174    }
7175
7176    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7177            final int modeFlags) {
7178        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7179        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7180                : UriPermission.STRENGTH_OWNED;
7181
7182        // Root gets to do everything.
7183        if (uid == 0) {
7184            return true;
7185        }
7186
7187        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7188        if (perms == null) return false;
7189
7190        // First look for exact match
7191        final UriPermission exactPerm = perms.get(grantUri);
7192        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7193            return true;
7194        }
7195
7196        // No exact match, look for prefixes
7197        final int N = perms.size();
7198        for (int i = 0; i < N; i++) {
7199            final UriPermission perm = perms.valueAt(i);
7200            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7201                    && perm.getStrength(modeFlags) >= minStrength) {
7202                return true;
7203            }
7204        }
7205
7206        return false;
7207    }
7208
7209    /**
7210     * @param uri This uri must NOT contain an embedded userId.
7211     * @param userId The userId in which the uri is to be resolved.
7212     */
7213    @Override
7214    public int checkUriPermission(Uri uri, int pid, int uid,
7215            final int modeFlags, int userId) {
7216        enforceNotIsolatedCaller("checkUriPermission");
7217
7218        // Another redirected-binder-call permissions check as in
7219        // {@link checkComponentPermission}.
7220        Identity tlsIdentity = sCallerIdentity.get();
7221        if (tlsIdentity != null) {
7222            uid = tlsIdentity.uid;
7223            pid = tlsIdentity.pid;
7224        }
7225
7226        // Our own process gets to do everything.
7227        if (pid == MY_PID) {
7228            return PackageManager.PERMISSION_GRANTED;
7229        }
7230        synchronized (this) {
7231            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7232                    ? PackageManager.PERMISSION_GRANTED
7233                    : PackageManager.PERMISSION_DENIED;
7234        }
7235    }
7236
7237    /**
7238     * Check if the targetPkg can be granted permission to access uri by
7239     * the callingUid using the given modeFlags.  Throws a security exception
7240     * if callingUid is not allowed to do this.  Returns the uid of the target
7241     * if the URI permission grant should be performed; returns -1 if it is not
7242     * needed (for example targetPkg already has permission to access the URI).
7243     * If you already know the uid of the target, you can supply it in
7244     * lastTargetUid else set that to -1.
7245     */
7246    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7247            final int modeFlags, int lastTargetUid) {
7248        if (!Intent.isAccessUriMode(modeFlags)) {
7249            return -1;
7250        }
7251
7252        if (targetPkg != null) {
7253            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7254                    "Checking grant " + targetPkg + " permission to " + grantUri);
7255        }
7256
7257        final IPackageManager pm = AppGlobals.getPackageManager();
7258
7259        // If this is not a content: uri, we can't do anything with it.
7260        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7261            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7262                    "Can't grant URI permission for non-content URI: " + grantUri);
7263            return -1;
7264        }
7265
7266        final String authority = grantUri.uri.getAuthority();
7267        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7268        if (pi == null) {
7269            Slog.w(TAG, "No content provider found for permission check: " +
7270                    grantUri.uri.toSafeString());
7271            return -1;
7272        }
7273
7274        int targetUid = lastTargetUid;
7275        if (targetUid < 0 && targetPkg != null) {
7276            try {
7277                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7278                if (targetUid < 0) {
7279                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7280                            "Can't grant URI permission no uid for: " + targetPkg);
7281                    return -1;
7282                }
7283            } catch (RemoteException ex) {
7284                return -1;
7285            }
7286        }
7287
7288        if (targetUid >= 0) {
7289            // First...  does the target actually need this permission?
7290            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7291                // No need to grant the target this permission.
7292                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7293                        "Target " + targetPkg + " already has full permission to " + grantUri);
7294                return -1;
7295            }
7296        } else {
7297            // First...  there is no target package, so can anyone access it?
7298            boolean allowed = pi.exported;
7299            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7300                if (pi.readPermission != null) {
7301                    allowed = false;
7302                }
7303            }
7304            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7305                if (pi.writePermission != null) {
7306                    allowed = false;
7307                }
7308            }
7309            if (allowed) {
7310                return -1;
7311            }
7312        }
7313
7314        /* There is a special cross user grant if:
7315         * - The target is on another user.
7316         * - Apps on the current user can access the uri without any uid permissions.
7317         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7318         * grant uri permissions.
7319         */
7320        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7321                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7322                modeFlags, false /*without considering the uid permissions*/);
7323
7324        // Second...  is the provider allowing granting of URI permissions?
7325        if (!specialCrossUserGrant) {
7326            if (!pi.grantUriPermissions) {
7327                throw new SecurityException("Provider " + pi.packageName
7328                        + "/" + pi.name
7329                        + " does not allow granting of Uri permissions (uri "
7330                        + grantUri + ")");
7331            }
7332            if (pi.uriPermissionPatterns != null) {
7333                final int N = pi.uriPermissionPatterns.length;
7334                boolean allowed = false;
7335                for (int i=0; i<N; i++) {
7336                    if (pi.uriPermissionPatterns[i] != null
7337                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7338                        allowed = true;
7339                        break;
7340                    }
7341                }
7342                if (!allowed) {
7343                    throw new SecurityException("Provider " + pi.packageName
7344                            + "/" + pi.name
7345                            + " does not allow granting of permission to path of Uri "
7346                            + grantUri);
7347                }
7348            }
7349        }
7350
7351        // Third...  does the caller itself have permission to access
7352        // this uri?
7353        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7354            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7355                // Require they hold a strong enough Uri permission
7356                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7357                    throw new SecurityException("Uid " + callingUid
7358                            + " does not have permission to uri " + grantUri);
7359                }
7360            }
7361        }
7362        return targetUid;
7363    }
7364
7365    /**
7366     * @param uri This uri must NOT contain an embedded userId.
7367     * @param userId The userId in which the uri is to be resolved.
7368     */
7369    @Override
7370    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7371            final int modeFlags, int userId) {
7372        enforceNotIsolatedCaller("checkGrantUriPermission");
7373        synchronized(this) {
7374            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7375                    new GrantUri(userId, uri, false), modeFlags, -1);
7376        }
7377    }
7378
7379    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7380            final int modeFlags, UriPermissionOwner owner) {
7381        if (!Intent.isAccessUriMode(modeFlags)) {
7382            return;
7383        }
7384
7385        // So here we are: the caller has the assumed permission
7386        // to the uri, and the target doesn't.  Let's now give this to
7387        // the target.
7388
7389        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7390                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7391
7392        final String authority = grantUri.uri.getAuthority();
7393        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7394        if (pi == null) {
7395            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7396            return;
7397        }
7398
7399        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7400            grantUri.prefix = true;
7401        }
7402        final UriPermission perm = findOrCreateUriPermissionLocked(
7403                pi.packageName, targetPkg, targetUid, grantUri);
7404        perm.grantModes(modeFlags, owner);
7405    }
7406
7407    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7408            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7409        if (targetPkg == null) {
7410            throw new NullPointerException("targetPkg");
7411        }
7412        int targetUid;
7413        final IPackageManager pm = AppGlobals.getPackageManager();
7414        try {
7415            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7416        } catch (RemoteException ex) {
7417            return;
7418        }
7419
7420        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7421                targetUid);
7422        if (targetUid < 0) {
7423            return;
7424        }
7425
7426        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7427                owner);
7428    }
7429
7430    static class NeededUriGrants extends ArrayList<GrantUri> {
7431        final String targetPkg;
7432        final int targetUid;
7433        final int flags;
7434
7435        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7436            this.targetPkg = targetPkg;
7437            this.targetUid = targetUid;
7438            this.flags = flags;
7439        }
7440    }
7441
7442    /**
7443     * Like checkGrantUriPermissionLocked, but takes an Intent.
7444     */
7445    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7446            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7447        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7448                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7449                + " clip=" + (intent != null ? intent.getClipData() : null)
7450                + " from " + intent + "; flags=0x"
7451                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7452
7453        if (targetPkg == null) {
7454            throw new NullPointerException("targetPkg");
7455        }
7456
7457        if (intent == null) {
7458            return null;
7459        }
7460        Uri data = intent.getData();
7461        ClipData clip = intent.getClipData();
7462        if (data == null && clip == null) {
7463            return null;
7464        }
7465        // Default userId for uris in the intent (if they don't specify it themselves)
7466        int contentUserHint = intent.getContentUserHint();
7467        if (contentUserHint == UserHandle.USER_CURRENT) {
7468            contentUserHint = UserHandle.getUserId(callingUid);
7469        }
7470        final IPackageManager pm = AppGlobals.getPackageManager();
7471        int targetUid;
7472        if (needed != null) {
7473            targetUid = needed.targetUid;
7474        } else {
7475            try {
7476                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7477            } catch (RemoteException ex) {
7478                return null;
7479            }
7480            if (targetUid < 0) {
7481                if (DEBUG_URI_PERMISSION) {
7482                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7483                            + " on user " + targetUserId);
7484                }
7485                return null;
7486            }
7487        }
7488        if (data != null) {
7489            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7490            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7491                    targetUid);
7492            if (targetUid > 0) {
7493                if (needed == null) {
7494                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7495                }
7496                needed.add(grantUri);
7497            }
7498        }
7499        if (clip != null) {
7500            for (int i=0; i<clip.getItemCount(); i++) {
7501                Uri uri = clip.getItemAt(i).getUri();
7502                if (uri != null) {
7503                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7504                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7505                            targetUid);
7506                    if (targetUid > 0) {
7507                        if (needed == null) {
7508                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7509                        }
7510                        needed.add(grantUri);
7511                    }
7512                } else {
7513                    Intent clipIntent = clip.getItemAt(i).getIntent();
7514                    if (clipIntent != null) {
7515                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7516                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7517                        if (newNeeded != null) {
7518                            needed = newNeeded;
7519                        }
7520                    }
7521                }
7522            }
7523        }
7524
7525        return needed;
7526    }
7527
7528    /**
7529     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7530     */
7531    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7532            UriPermissionOwner owner) {
7533        if (needed != null) {
7534            for (int i=0; i<needed.size(); i++) {
7535                GrantUri grantUri = needed.get(i);
7536                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7537                        grantUri, needed.flags, owner);
7538            }
7539        }
7540    }
7541
7542    void grantUriPermissionFromIntentLocked(int callingUid,
7543            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7544        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7545                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7546        if (needed == null) {
7547            return;
7548        }
7549
7550        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7551    }
7552
7553    /**
7554     * @param uri This uri must NOT contain an embedded userId.
7555     * @param userId The userId in which the uri is to be resolved.
7556     */
7557    @Override
7558    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7559            final int modeFlags, int userId) {
7560        enforceNotIsolatedCaller("grantUriPermission");
7561        GrantUri grantUri = new GrantUri(userId, uri, false);
7562        synchronized(this) {
7563            final ProcessRecord r = getRecordForAppLocked(caller);
7564            if (r == null) {
7565                throw new SecurityException("Unable to find app for caller "
7566                        + caller
7567                        + " when granting permission to uri " + grantUri);
7568            }
7569            if (targetPkg == null) {
7570                throw new IllegalArgumentException("null target");
7571            }
7572            if (grantUri == null) {
7573                throw new IllegalArgumentException("null uri");
7574            }
7575
7576            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7577                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7578                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7579                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7580
7581            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7582                    UserHandle.getUserId(r.uid));
7583        }
7584    }
7585
7586    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7587        if (perm.modeFlags == 0) {
7588            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7589                    perm.targetUid);
7590            if (perms != null) {
7591                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7592                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7593
7594                perms.remove(perm.uri);
7595                if (perms.isEmpty()) {
7596                    mGrantedUriPermissions.remove(perm.targetUid);
7597                }
7598            }
7599        }
7600    }
7601
7602    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7603        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7604
7605        final IPackageManager pm = AppGlobals.getPackageManager();
7606        final String authority = grantUri.uri.getAuthority();
7607        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7608        if (pi == null) {
7609            Slog.w(TAG, "No content provider found for permission revoke: "
7610                    + grantUri.toSafeString());
7611            return;
7612        }
7613
7614        // Does the caller have this permission on the URI?
7615        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7616            // If they don't have direct access to the URI, then revoke any
7617            // ownerless URI permissions that have been granted to them.
7618            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7619            if (perms != null) {
7620                boolean persistChanged = false;
7621                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7622                    final UriPermission perm = it.next();
7623                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7624                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7625                        if (DEBUG_URI_PERMISSION)
7626                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7627                                    " permission to " + perm.uri);
7628                        persistChanged |= perm.revokeModes(
7629                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7630                        if (perm.modeFlags == 0) {
7631                            it.remove();
7632                        }
7633                    }
7634                }
7635                if (perms.isEmpty()) {
7636                    mGrantedUriPermissions.remove(callingUid);
7637                }
7638                if (persistChanged) {
7639                    schedulePersistUriGrants();
7640                }
7641            }
7642            return;
7643        }
7644
7645        boolean persistChanged = false;
7646
7647        // Go through all of the permissions and remove any that match.
7648        int N = mGrantedUriPermissions.size();
7649        for (int i = 0; i < N; i++) {
7650            final int targetUid = mGrantedUriPermissions.keyAt(i);
7651            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7652
7653            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7654                final UriPermission perm = it.next();
7655                if (perm.uri.sourceUserId == grantUri.sourceUserId
7656                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7657                    if (DEBUG_URI_PERMISSION)
7658                        Slog.v(TAG,
7659                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7660                    persistChanged |= perm.revokeModes(
7661                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7662                    if (perm.modeFlags == 0) {
7663                        it.remove();
7664                    }
7665                }
7666            }
7667
7668            if (perms.isEmpty()) {
7669                mGrantedUriPermissions.remove(targetUid);
7670                N--;
7671                i--;
7672            }
7673        }
7674
7675        if (persistChanged) {
7676            schedulePersistUriGrants();
7677        }
7678    }
7679
7680    /**
7681     * @param uri This uri must NOT contain an embedded userId.
7682     * @param userId The userId in which the uri is to be resolved.
7683     */
7684    @Override
7685    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7686            int userId) {
7687        enforceNotIsolatedCaller("revokeUriPermission");
7688        synchronized(this) {
7689            final ProcessRecord r = getRecordForAppLocked(caller);
7690            if (r == null) {
7691                throw new SecurityException("Unable to find app for caller "
7692                        + caller
7693                        + " when revoking permission to uri " + uri);
7694            }
7695            if (uri == null) {
7696                Slog.w(TAG, "revokeUriPermission: null uri");
7697                return;
7698            }
7699
7700            if (!Intent.isAccessUriMode(modeFlags)) {
7701                return;
7702            }
7703
7704            final IPackageManager pm = AppGlobals.getPackageManager();
7705            final String authority = uri.getAuthority();
7706            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7707            if (pi == null) {
7708                Slog.w(TAG, "No content provider found for permission revoke: "
7709                        + uri.toSafeString());
7710                return;
7711            }
7712
7713            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7714        }
7715    }
7716
7717    /**
7718     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7719     * given package.
7720     *
7721     * @param packageName Package name to match, or {@code null} to apply to all
7722     *            packages.
7723     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7724     *            to all users.
7725     * @param persistable If persistable grants should be removed.
7726     */
7727    private void removeUriPermissionsForPackageLocked(
7728            String packageName, int userHandle, boolean persistable) {
7729        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7730            throw new IllegalArgumentException("Must narrow by either package or user");
7731        }
7732
7733        boolean persistChanged = false;
7734
7735        int N = mGrantedUriPermissions.size();
7736        for (int i = 0; i < N; i++) {
7737            final int targetUid = mGrantedUriPermissions.keyAt(i);
7738            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7739
7740            // Only inspect grants matching user
7741            if (userHandle == UserHandle.USER_ALL
7742                    || userHandle == UserHandle.getUserId(targetUid)) {
7743                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7744                    final UriPermission perm = it.next();
7745
7746                    // Only inspect grants matching package
7747                    if (packageName == null || perm.sourcePkg.equals(packageName)
7748                            || perm.targetPkg.equals(packageName)) {
7749                        persistChanged |= perm.revokeModes(persistable
7750                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7751
7752                        // Only remove when no modes remain; any persisted grants
7753                        // will keep this alive.
7754                        if (perm.modeFlags == 0) {
7755                            it.remove();
7756                        }
7757                    }
7758                }
7759
7760                if (perms.isEmpty()) {
7761                    mGrantedUriPermissions.remove(targetUid);
7762                    N--;
7763                    i--;
7764                }
7765            }
7766        }
7767
7768        if (persistChanged) {
7769            schedulePersistUriGrants();
7770        }
7771    }
7772
7773    @Override
7774    public IBinder newUriPermissionOwner(String name) {
7775        enforceNotIsolatedCaller("newUriPermissionOwner");
7776        synchronized(this) {
7777            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7778            return owner.getExternalTokenLocked();
7779        }
7780    }
7781
7782    /**
7783     * @param uri This uri must NOT contain an embedded userId.
7784     * @param sourceUserId The userId in which the uri is to be resolved.
7785     * @param targetUserId The userId of the app that receives the grant.
7786     */
7787    @Override
7788    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7789            final int modeFlags, int sourceUserId, int targetUserId) {
7790        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7791                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7792        synchronized(this) {
7793            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7794            if (owner == null) {
7795                throw new IllegalArgumentException("Unknown owner: " + token);
7796            }
7797            if (fromUid != Binder.getCallingUid()) {
7798                if (Binder.getCallingUid() != Process.myUid()) {
7799                    // Only system code can grant URI permissions on behalf
7800                    // of other users.
7801                    throw new SecurityException("nice try");
7802                }
7803            }
7804            if (targetPkg == null) {
7805                throw new IllegalArgumentException("null target");
7806            }
7807            if (uri == null) {
7808                throw new IllegalArgumentException("null uri");
7809            }
7810
7811            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7812                    modeFlags, owner, targetUserId);
7813        }
7814    }
7815
7816    /**
7817     * @param uri This uri must NOT contain an embedded userId.
7818     * @param userId The userId in which the uri is to be resolved.
7819     */
7820    @Override
7821    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7822        synchronized(this) {
7823            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7824            if (owner == null) {
7825                throw new IllegalArgumentException("Unknown owner: " + token);
7826            }
7827
7828            if (uri == null) {
7829                owner.removeUriPermissionsLocked(mode);
7830            } else {
7831                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7832            }
7833        }
7834    }
7835
7836    private void schedulePersistUriGrants() {
7837        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7838            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7839                    10 * DateUtils.SECOND_IN_MILLIS);
7840        }
7841    }
7842
7843    private void writeGrantedUriPermissions() {
7844        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7845
7846        // Snapshot permissions so we can persist without lock
7847        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7848        synchronized (this) {
7849            final int size = mGrantedUriPermissions.size();
7850            for (int i = 0; i < size; i++) {
7851                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7852                for (UriPermission perm : perms.values()) {
7853                    if (perm.persistedModeFlags != 0) {
7854                        persist.add(perm.snapshot());
7855                    }
7856                }
7857            }
7858        }
7859
7860        FileOutputStream fos = null;
7861        try {
7862            fos = mGrantFile.startWrite();
7863
7864            XmlSerializer out = new FastXmlSerializer();
7865            out.setOutput(fos, "utf-8");
7866            out.startDocument(null, true);
7867            out.startTag(null, TAG_URI_GRANTS);
7868            for (UriPermission.Snapshot perm : persist) {
7869                out.startTag(null, TAG_URI_GRANT);
7870                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7871                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7872                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7873                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7874                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7875                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7876                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7877                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7878                out.endTag(null, TAG_URI_GRANT);
7879            }
7880            out.endTag(null, TAG_URI_GRANTS);
7881            out.endDocument();
7882
7883            mGrantFile.finishWrite(fos);
7884        } catch (IOException e) {
7885            if (fos != null) {
7886                mGrantFile.failWrite(fos);
7887            }
7888        }
7889    }
7890
7891    private void readGrantedUriPermissionsLocked() {
7892        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7893
7894        final long now = System.currentTimeMillis();
7895
7896        FileInputStream fis = null;
7897        try {
7898            fis = mGrantFile.openRead();
7899            final XmlPullParser in = Xml.newPullParser();
7900            in.setInput(fis, null);
7901
7902            int type;
7903            while ((type = in.next()) != END_DOCUMENT) {
7904                final String tag = in.getName();
7905                if (type == START_TAG) {
7906                    if (TAG_URI_GRANT.equals(tag)) {
7907                        final int sourceUserId;
7908                        final int targetUserId;
7909                        final int userHandle = readIntAttribute(in,
7910                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7911                        if (userHandle != UserHandle.USER_NULL) {
7912                            // For backwards compatibility.
7913                            sourceUserId = userHandle;
7914                            targetUserId = userHandle;
7915                        } else {
7916                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7917                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7918                        }
7919                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7920                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7921                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7922                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7923                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7924                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7925
7926                        // Sanity check that provider still belongs to source package
7927                        final ProviderInfo pi = getProviderInfoLocked(
7928                                uri.getAuthority(), sourceUserId);
7929                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7930                            int targetUid = -1;
7931                            try {
7932                                targetUid = AppGlobals.getPackageManager()
7933                                        .getPackageUid(targetPkg, targetUserId);
7934                            } catch (RemoteException e) {
7935                            }
7936                            if (targetUid != -1) {
7937                                final UriPermission perm = findOrCreateUriPermissionLocked(
7938                                        sourcePkg, targetPkg, targetUid,
7939                                        new GrantUri(sourceUserId, uri, prefix));
7940                                perm.initPersistedModes(modeFlags, createdTime);
7941                            }
7942                        } else {
7943                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7944                                    + " but instead found " + pi);
7945                        }
7946                    }
7947                }
7948            }
7949        } catch (FileNotFoundException e) {
7950            // Missing grants is okay
7951        } catch (IOException e) {
7952            Slog.wtf(TAG, "Failed reading Uri grants", e);
7953        } catch (XmlPullParserException e) {
7954            Slog.wtf(TAG, "Failed reading Uri grants", e);
7955        } finally {
7956            IoUtils.closeQuietly(fis);
7957        }
7958    }
7959
7960    /**
7961     * @param uri This uri must NOT contain an embedded userId.
7962     * @param userId The userId in which the uri is to be resolved.
7963     */
7964    @Override
7965    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7966        enforceNotIsolatedCaller("takePersistableUriPermission");
7967
7968        Preconditions.checkFlagsArgument(modeFlags,
7969                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7970
7971        synchronized (this) {
7972            final int callingUid = Binder.getCallingUid();
7973            boolean persistChanged = false;
7974            GrantUri grantUri = new GrantUri(userId, uri, false);
7975
7976            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7977                    new GrantUri(userId, uri, false));
7978            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7979                    new GrantUri(userId, uri, true));
7980
7981            final boolean exactValid = (exactPerm != null)
7982                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7983            final boolean prefixValid = (prefixPerm != null)
7984                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7985
7986            if (!(exactValid || prefixValid)) {
7987                throw new SecurityException("No persistable permission grants found for UID "
7988                        + callingUid + " and Uri " + grantUri.toSafeString());
7989            }
7990
7991            if (exactValid) {
7992                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7993            }
7994            if (prefixValid) {
7995                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7996            }
7997
7998            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7999
8000            if (persistChanged) {
8001                schedulePersistUriGrants();
8002            }
8003        }
8004    }
8005
8006    /**
8007     * @param uri This uri must NOT contain an embedded userId.
8008     * @param userId The userId in which the uri is to be resolved.
8009     */
8010    @Override
8011    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8012        enforceNotIsolatedCaller("releasePersistableUriPermission");
8013
8014        Preconditions.checkFlagsArgument(modeFlags,
8015                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8016
8017        synchronized (this) {
8018            final int callingUid = Binder.getCallingUid();
8019            boolean persistChanged = false;
8020
8021            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8022                    new GrantUri(userId, uri, false));
8023            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8024                    new GrantUri(userId, uri, true));
8025            if (exactPerm == null && prefixPerm == null) {
8026                throw new SecurityException("No permission grants found for UID " + callingUid
8027                        + " and Uri " + uri.toSafeString());
8028            }
8029
8030            if (exactPerm != null) {
8031                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8032                removeUriPermissionIfNeededLocked(exactPerm);
8033            }
8034            if (prefixPerm != null) {
8035                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8036                removeUriPermissionIfNeededLocked(prefixPerm);
8037            }
8038
8039            if (persistChanged) {
8040                schedulePersistUriGrants();
8041            }
8042        }
8043    }
8044
8045    /**
8046     * Prune any older {@link UriPermission} for the given UID until outstanding
8047     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8048     *
8049     * @return if any mutations occured that require persisting.
8050     */
8051    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8052        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8053        if (perms == null) return false;
8054        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8055
8056        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8057        for (UriPermission perm : perms.values()) {
8058            if (perm.persistedModeFlags != 0) {
8059                persisted.add(perm);
8060            }
8061        }
8062
8063        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8064        if (trimCount <= 0) return false;
8065
8066        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8067        for (int i = 0; i < trimCount; i++) {
8068            final UriPermission perm = persisted.get(i);
8069
8070            if (DEBUG_URI_PERMISSION) {
8071                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8072            }
8073
8074            perm.releasePersistableModes(~0);
8075            removeUriPermissionIfNeededLocked(perm);
8076        }
8077
8078        return true;
8079    }
8080
8081    @Override
8082    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8083            String packageName, boolean incoming) {
8084        enforceNotIsolatedCaller("getPersistedUriPermissions");
8085        Preconditions.checkNotNull(packageName, "packageName");
8086
8087        final int callingUid = Binder.getCallingUid();
8088        final IPackageManager pm = AppGlobals.getPackageManager();
8089        try {
8090            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8091            if (packageUid != callingUid) {
8092                throw new SecurityException(
8093                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8094            }
8095        } catch (RemoteException e) {
8096            throw new SecurityException("Failed to verify package name ownership");
8097        }
8098
8099        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8100        synchronized (this) {
8101            if (incoming) {
8102                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8103                        callingUid);
8104                if (perms == null) {
8105                    Slog.w(TAG, "No permission grants found for " + packageName);
8106                } else {
8107                    for (UriPermission perm : perms.values()) {
8108                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8109                            result.add(perm.buildPersistedPublicApiObject());
8110                        }
8111                    }
8112                }
8113            } else {
8114                final int size = mGrantedUriPermissions.size();
8115                for (int i = 0; i < size; i++) {
8116                    final ArrayMap<GrantUri, UriPermission> perms =
8117                            mGrantedUriPermissions.valueAt(i);
8118                    for (UriPermission perm : perms.values()) {
8119                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8120                            result.add(perm.buildPersistedPublicApiObject());
8121                        }
8122                    }
8123                }
8124            }
8125        }
8126        return new ParceledListSlice<android.content.UriPermission>(result);
8127    }
8128
8129    @Override
8130    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8131        synchronized (this) {
8132            ProcessRecord app =
8133                who != null ? getRecordForAppLocked(who) : null;
8134            if (app == null) return;
8135
8136            Message msg = Message.obtain();
8137            msg.what = WAIT_FOR_DEBUGGER_MSG;
8138            msg.obj = app;
8139            msg.arg1 = waiting ? 1 : 0;
8140            mHandler.sendMessage(msg);
8141        }
8142    }
8143
8144    @Override
8145    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8146        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8147        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8148        outInfo.availMem = Process.getFreeMemory();
8149        outInfo.totalMem = Process.getTotalMemory();
8150        outInfo.threshold = homeAppMem;
8151        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8152        outInfo.hiddenAppThreshold = cachedAppMem;
8153        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8154                ProcessList.SERVICE_ADJ);
8155        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8156                ProcessList.VISIBLE_APP_ADJ);
8157        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8158                ProcessList.FOREGROUND_APP_ADJ);
8159    }
8160
8161    // =========================================================
8162    // TASK MANAGEMENT
8163    // =========================================================
8164
8165    @Override
8166    public List<IAppTask> getAppTasks(String callingPackage) {
8167        int callingUid = Binder.getCallingUid();
8168        long ident = Binder.clearCallingIdentity();
8169
8170        synchronized(this) {
8171            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8172            try {
8173                if (localLOGV) Slog.v(TAG, "getAppTasks");
8174
8175                final int N = mRecentTasks.size();
8176                for (int i = 0; i < N; i++) {
8177                    TaskRecord tr = mRecentTasks.get(i);
8178                    // Skip tasks that do not match the caller.  We don't need to verify
8179                    // callingPackage, because we are also limiting to callingUid and know
8180                    // that will limit to the correct security sandbox.
8181                    if (tr.effectiveUid != callingUid) {
8182                        continue;
8183                    }
8184                    Intent intent = tr.getBaseIntent();
8185                    if (intent == null ||
8186                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8187                        continue;
8188                    }
8189                    ActivityManager.RecentTaskInfo taskInfo =
8190                            createRecentTaskInfoFromTaskRecord(tr);
8191                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8192                    list.add(taskImpl);
8193                }
8194            } finally {
8195                Binder.restoreCallingIdentity(ident);
8196            }
8197            return list;
8198        }
8199    }
8200
8201    @Override
8202    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8203        final int callingUid = Binder.getCallingUid();
8204        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8205
8206        synchronized(this) {
8207            if (localLOGV) Slog.v(
8208                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8209
8210            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8211                    callingUid);
8212
8213            // TODO: Improve with MRU list from all ActivityStacks.
8214            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8215        }
8216
8217        return list;
8218    }
8219
8220    TaskRecord getMostRecentTask() {
8221        return mRecentTasks.get(0);
8222    }
8223
8224    /**
8225     * Creates a new RecentTaskInfo from a TaskRecord.
8226     */
8227    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8228        // Update the task description to reflect any changes in the task stack
8229        tr.updateTaskDescription();
8230
8231        // Compose the recent task info
8232        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8233        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8234        rti.persistentId = tr.taskId;
8235        rti.baseIntent = new Intent(tr.getBaseIntent());
8236        rti.origActivity = tr.origActivity;
8237        rti.description = tr.lastDescription;
8238        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8239        rti.userId = tr.userId;
8240        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8241        rti.firstActiveTime = tr.firstActiveTime;
8242        rti.lastActiveTime = tr.lastActiveTime;
8243        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8244        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8245        return rti;
8246    }
8247
8248    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8249        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8250                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8251        if (!allowed) {
8252            if (checkPermission(android.Manifest.permission.GET_TASKS,
8253                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8254                // Temporary compatibility: some existing apps on the system image may
8255                // still be requesting the old permission and not switched to the new
8256                // one; if so, we'll still allow them full access.  This means we need
8257                // to see if they are holding the old permission and are a system app.
8258                try {
8259                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8260                        allowed = true;
8261                        Slog.w(TAG, caller + ": caller " + callingUid
8262                                + " is using old GET_TASKS but privileged; allowing");
8263                    }
8264                } catch (RemoteException e) {
8265                }
8266            }
8267        }
8268        if (!allowed) {
8269            Slog.w(TAG, caller + ": caller " + callingUid
8270                    + " does not hold GET_TASKS; limiting output");
8271        }
8272        return allowed;
8273    }
8274
8275    @Override
8276    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8277        final int callingUid = Binder.getCallingUid();
8278        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8279                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8280
8281        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8282        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8283        synchronized (this) {
8284            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8285                    callingUid);
8286            final boolean detailed = checkCallingPermission(
8287                    android.Manifest.permission.GET_DETAILED_TASKS)
8288                    == PackageManager.PERMISSION_GRANTED;
8289
8290            final int N = mRecentTasks.size();
8291            ArrayList<ActivityManager.RecentTaskInfo> res
8292                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8293                            maxNum < N ? maxNum : N);
8294
8295            final Set<Integer> includedUsers;
8296            if (includeProfiles) {
8297                includedUsers = getProfileIdsLocked(userId);
8298            } else {
8299                includedUsers = new HashSet<Integer>();
8300            }
8301            includedUsers.add(Integer.valueOf(userId));
8302
8303            for (int i=0; i<N && maxNum > 0; i++) {
8304                TaskRecord tr = mRecentTasks.get(i);
8305                // Only add calling user or related users recent tasks
8306                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8307                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8308                    continue;
8309                }
8310
8311                // Return the entry if desired by the caller.  We always return
8312                // the first entry, because callers always expect this to be the
8313                // foreground app.  We may filter others if the caller has
8314                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8315                // we should exclude the entry.
8316
8317                if (i == 0
8318                        || withExcluded
8319                        || (tr.intent == null)
8320                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8321                                == 0)) {
8322                    if (!allowed) {
8323                        // If the caller doesn't have the GET_TASKS permission, then only
8324                        // allow them to see a small subset of tasks -- their own and home.
8325                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8326                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8327                            continue;
8328                        }
8329                    }
8330                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8331                        if (tr.stack != null && tr.stack.isHomeStack()) {
8332                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8333                            continue;
8334                        }
8335                    }
8336                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8337                        // Don't include auto remove tasks that are finished or finishing.
8338                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8339                                + tr);
8340                        continue;
8341                    }
8342                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8343                            && !tr.isAvailable) {
8344                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8345                        continue;
8346                    }
8347
8348                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8349                    if (!detailed) {
8350                        rti.baseIntent.replaceExtras((Bundle)null);
8351                    }
8352
8353                    res.add(rti);
8354                    maxNum--;
8355                }
8356            }
8357            return res;
8358        }
8359    }
8360
8361    private TaskRecord recentTaskForIdLocked(int id) {
8362        final int N = mRecentTasks.size();
8363            for (int i=0; i<N; i++) {
8364                TaskRecord tr = mRecentTasks.get(i);
8365                if (tr.taskId == id) {
8366                    return tr;
8367                }
8368            }
8369            return null;
8370    }
8371
8372    @Override
8373    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8374        synchronized (this) {
8375            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8376                    "getTaskThumbnail()");
8377            TaskRecord tr = recentTaskForIdLocked(id);
8378            if (tr != null) {
8379                return tr.getTaskThumbnailLocked();
8380            }
8381        }
8382        return null;
8383    }
8384
8385    @Override
8386    public int addAppTask(IBinder activityToken, Intent intent,
8387            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8388        final int callingUid = Binder.getCallingUid();
8389        final long callingIdent = Binder.clearCallingIdentity();
8390
8391        try {
8392            synchronized (this) {
8393                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8394                if (r == null) {
8395                    throw new IllegalArgumentException("Activity does not exist; token="
8396                            + activityToken);
8397                }
8398                ComponentName comp = intent.getComponent();
8399                if (comp == null) {
8400                    throw new IllegalArgumentException("Intent " + intent
8401                            + " must specify explicit component");
8402                }
8403                if (thumbnail.getWidth() != mThumbnailWidth
8404                        || thumbnail.getHeight() != mThumbnailHeight) {
8405                    throw new IllegalArgumentException("Bad thumbnail size: got "
8406                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8407                            + mThumbnailWidth + "x" + mThumbnailHeight);
8408                }
8409                if (intent.getSelector() != null) {
8410                    intent.setSelector(null);
8411                }
8412                if (intent.getSourceBounds() != null) {
8413                    intent.setSourceBounds(null);
8414                }
8415                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8416                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8417                        // The caller has added this as an auto-remove task...  that makes no
8418                        // sense, so turn off auto-remove.
8419                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8420                    }
8421                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8422                    // Must be a new task.
8423                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8424                }
8425                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8426                    mLastAddedTaskActivity = null;
8427                }
8428                ActivityInfo ainfo = mLastAddedTaskActivity;
8429                if (ainfo == null) {
8430                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8431                            comp, 0, UserHandle.getUserId(callingUid));
8432                    if (ainfo.applicationInfo.uid != callingUid) {
8433                        throw new SecurityException(
8434                                "Can't add task for another application: target uid="
8435                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8436                    }
8437                }
8438
8439                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8440                        intent, description);
8441
8442                int trimIdx = trimRecentsForTask(task, false);
8443                if (trimIdx >= 0) {
8444                    // If this would have caused a trim, then we'll abort because that
8445                    // means it would be added at the end of the list but then just removed.
8446                    return -1;
8447                }
8448
8449                final int N = mRecentTasks.size();
8450                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8451                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8452                    tr.removedFromRecents(mTaskPersister);
8453                }
8454
8455                task.inRecents = true;
8456                mRecentTasks.add(task);
8457                r.task.stack.addTask(task, false, false);
8458
8459                task.setLastThumbnail(thumbnail);
8460                task.freeLastThumbnail();
8461
8462                return task.taskId;
8463            }
8464        } finally {
8465            Binder.restoreCallingIdentity(callingIdent);
8466        }
8467    }
8468
8469    @Override
8470    public Point getAppTaskThumbnailSize() {
8471        synchronized (this) {
8472            return new Point(mThumbnailWidth,  mThumbnailHeight);
8473        }
8474    }
8475
8476    @Override
8477    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8478        synchronized (this) {
8479            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8480            if (r != null) {
8481                r.setTaskDescription(td);
8482                r.task.updateTaskDescription();
8483            }
8484        }
8485    }
8486
8487    @Override
8488    public Bitmap getTaskDescriptionIcon(String filename) {
8489        if (!FileUtils.isValidExtFilename(filename)
8490                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8491            throw new IllegalArgumentException("Bad filename: " + filename);
8492        }
8493        return mTaskPersister.getTaskDescriptionIcon(filename);
8494    }
8495
8496    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8497        mRecentTasks.remove(tr);
8498        tr.removedFromRecents(mTaskPersister);
8499        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8500        Intent baseIntent = new Intent(
8501                tr.intent != null ? tr.intent : tr.affinityIntent);
8502        ComponentName component = baseIntent.getComponent();
8503        if (component == null) {
8504            Slog.w(TAG, "Now component for base intent of task: " + tr);
8505            return;
8506        }
8507
8508        // Find any running services associated with this app.
8509        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8510
8511        if (killProcesses) {
8512            // Find any running processes associated with this app.
8513            final String pkg = component.getPackageName();
8514            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8515            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8516            for (int i=0; i<pmap.size(); i++) {
8517                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8518                for (int j=0; j<uids.size(); j++) {
8519                    ProcessRecord proc = uids.valueAt(j);
8520                    if (proc.userId != tr.userId) {
8521                        continue;
8522                    }
8523                    if (!proc.pkgList.containsKey(pkg)) {
8524                        continue;
8525                    }
8526                    procs.add(proc);
8527                }
8528            }
8529
8530            // Kill the running processes.
8531            for (int i=0; i<procs.size(); i++) {
8532                ProcessRecord pr = procs.get(i);
8533                if (pr == mHomeProcess) {
8534                    // Don't kill the home process along with tasks from the same package.
8535                    continue;
8536                }
8537                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8538                    pr.kill("remove task", true);
8539                } else {
8540                    pr.waitingToKill = "remove task";
8541                }
8542            }
8543        }
8544    }
8545
8546    /**
8547     * Removes the task with the specified task id.
8548     *
8549     * @param taskId Identifier of the task to be removed.
8550     * @param flags Additional operational flags.  May be 0 or
8551     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8552     * @return Returns true if the given task was found and removed.
8553     */
8554    private boolean removeTaskByIdLocked(int taskId, int flags) {
8555        TaskRecord tr = recentTaskForIdLocked(taskId);
8556        if (tr != null) {
8557            tr.removeTaskActivitiesLocked();
8558            cleanUpRemovedTaskLocked(tr, flags);
8559            if (tr.isPersistable) {
8560                notifyTaskPersisterLocked(null, true);
8561            }
8562            return true;
8563        }
8564        return false;
8565    }
8566
8567    @Override
8568    public boolean removeTask(int taskId, int flags) {
8569        synchronized (this) {
8570            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8571                    "removeTask()");
8572            long ident = Binder.clearCallingIdentity();
8573            try {
8574                return removeTaskByIdLocked(taskId, flags);
8575            } finally {
8576                Binder.restoreCallingIdentity(ident);
8577            }
8578        }
8579    }
8580
8581    /**
8582     * TODO: Add mController hook
8583     */
8584    @Override
8585    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8586        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8587                "moveTaskToFront()");
8588
8589        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8590        synchronized(this) {
8591            moveTaskToFrontLocked(taskId, flags, options);
8592        }
8593    }
8594
8595    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8596        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8597                Binder.getCallingUid(), -1, -1, "Task to front")) {
8598            ActivityOptions.abort(options);
8599            return;
8600        }
8601        final long origId = Binder.clearCallingIdentity();
8602        try {
8603            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8604            if (task == null) {
8605                return;
8606            }
8607            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8608                mStackSupervisor.showLockTaskToast();
8609                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8610                return;
8611            }
8612            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8613            if (prev != null && prev.isRecentsActivity()) {
8614                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8615            }
8616            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8617        } finally {
8618            Binder.restoreCallingIdentity(origId);
8619        }
8620        ActivityOptions.abort(options);
8621    }
8622
8623    @Override
8624    public void moveTaskToBack(int taskId) {
8625        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8626                "moveTaskToBack()");
8627
8628        synchronized(this) {
8629            TaskRecord tr = recentTaskForIdLocked(taskId);
8630            if (tr != null) {
8631                if (tr == mStackSupervisor.mLockTaskModeTask) {
8632                    mStackSupervisor.showLockTaskToast();
8633                    return;
8634                }
8635                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8636                ActivityStack stack = tr.stack;
8637                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8638                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8639                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8640                        return;
8641                    }
8642                }
8643                final long origId = Binder.clearCallingIdentity();
8644                try {
8645                    stack.moveTaskToBackLocked(taskId, null);
8646                } finally {
8647                    Binder.restoreCallingIdentity(origId);
8648                }
8649            }
8650        }
8651    }
8652
8653    /**
8654     * Moves an activity, and all of the other activities within the same task, to the bottom
8655     * of the history stack.  The activity's order within the task is unchanged.
8656     *
8657     * @param token A reference to the activity we wish to move
8658     * @param nonRoot If false then this only works if the activity is the root
8659     *                of a task; if true it will work for any activity in a task.
8660     * @return Returns true if the move completed, false if not.
8661     */
8662    @Override
8663    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8664        enforceNotIsolatedCaller("moveActivityTaskToBack");
8665        synchronized(this) {
8666            final long origId = Binder.clearCallingIdentity();
8667            try {
8668                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8669                if (taskId >= 0) {
8670                    if ((mStackSupervisor.mLockTaskModeTask != null)
8671                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8672                        mStackSupervisor.showLockTaskToast();
8673                        return false;
8674                    }
8675                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8676                }
8677            } finally {
8678                Binder.restoreCallingIdentity(origId);
8679            }
8680        }
8681        return false;
8682    }
8683
8684    @Override
8685    public void moveTaskBackwards(int task) {
8686        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8687                "moveTaskBackwards()");
8688
8689        synchronized(this) {
8690            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8691                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8692                return;
8693            }
8694            final long origId = Binder.clearCallingIdentity();
8695            moveTaskBackwardsLocked(task);
8696            Binder.restoreCallingIdentity(origId);
8697        }
8698    }
8699
8700    private final void moveTaskBackwardsLocked(int task) {
8701        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8702    }
8703
8704    @Override
8705    public IBinder getHomeActivityToken() throws RemoteException {
8706        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8707                "getHomeActivityToken()");
8708        synchronized (this) {
8709            return mStackSupervisor.getHomeActivityToken();
8710        }
8711    }
8712
8713    @Override
8714    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8715            IActivityContainerCallback callback) throws RemoteException {
8716        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8717                "createActivityContainer()");
8718        synchronized (this) {
8719            if (parentActivityToken == null) {
8720                throw new IllegalArgumentException("parent token must not be null");
8721            }
8722            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8723            if (r == null) {
8724                return null;
8725            }
8726            if (callback == null) {
8727                throw new IllegalArgumentException("callback must not be null");
8728            }
8729            return mStackSupervisor.createActivityContainer(r, callback);
8730        }
8731    }
8732
8733    @Override
8734    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8735        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8736                "deleteActivityContainer()");
8737        synchronized (this) {
8738            mStackSupervisor.deleteActivityContainer(container);
8739        }
8740    }
8741
8742    @Override
8743    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8744            throws RemoteException {
8745        synchronized (this) {
8746            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8747            if (stack != null) {
8748                return stack.mActivityContainer;
8749            }
8750            return null;
8751        }
8752    }
8753
8754    @Override
8755    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8756        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8757                "moveTaskToStack()");
8758        if (stackId == HOME_STACK_ID) {
8759            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8760                    new RuntimeException("here").fillInStackTrace());
8761        }
8762        synchronized (this) {
8763            long ident = Binder.clearCallingIdentity();
8764            try {
8765                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8766                        + stackId + " toTop=" + toTop);
8767                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8768            } finally {
8769                Binder.restoreCallingIdentity(ident);
8770            }
8771        }
8772    }
8773
8774    @Override
8775    public void resizeStack(int stackBoxId, Rect bounds) {
8776        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8777                "resizeStackBox()");
8778        long ident = Binder.clearCallingIdentity();
8779        try {
8780            mWindowManager.resizeStack(stackBoxId, bounds);
8781        } finally {
8782            Binder.restoreCallingIdentity(ident);
8783        }
8784    }
8785
8786    @Override
8787    public List<StackInfo> getAllStackInfos() {
8788        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8789                "getAllStackInfos()");
8790        long ident = Binder.clearCallingIdentity();
8791        try {
8792            synchronized (this) {
8793                return mStackSupervisor.getAllStackInfosLocked();
8794            }
8795        } finally {
8796            Binder.restoreCallingIdentity(ident);
8797        }
8798    }
8799
8800    @Override
8801    public StackInfo getStackInfo(int stackId) {
8802        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8803                "getStackInfo()");
8804        long ident = Binder.clearCallingIdentity();
8805        try {
8806            synchronized (this) {
8807                return mStackSupervisor.getStackInfoLocked(stackId);
8808            }
8809        } finally {
8810            Binder.restoreCallingIdentity(ident);
8811        }
8812    }
8813
8814    @Override
8815    public boolean isInHomeStack(int taskId) {
8816        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8817                "getStackInfo()");
8818        long ident = Binder.clearCallingIdentity();
8819        try {
8820            synchronized (this) {
8821                TaskRecord tr = recentTaskForIdLocked(taskId);
8822                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8823            }
8824        } finally {
8825            Binder.restoreCallingIdentity(ident);
8826        }
8827    }
8828
8829    @Override
8830    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8831        synchronized(this) {
8832            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8833        }
8834    }
8835
8836    private boolean isLockTaskAuthorized(String pkg) {
8837        final DevicePolicyManager dpm = (DevicePolicyManager)
8838                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8839        try {
8840            int uid = mContext.getPackageManager().getPackageUid(pkg,
8841                    Binder.getCallingUserHandle().getIdentifier());
8842            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8843        } catch (NameNotFoundException e) {
8844            return false;
8845        }
8846    }
8847
8848    void startLockTaskMode(TaskRecord task) {
8849        final String pkg;
8850        synchronized (this) {
8851            pkg = task.intent.getComponent().getPackageName();
8852        }
8853        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8854        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8855            final TaskRecord taskRecord = task;
8856            mHandler.post(new Runnable() {
8857                @Override
8858                public void run() {
8859                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8860                }
8861            });
8862            return;
8863        }
8864        long ident = Binder.clearCallingIdentity();
8865        try {
8866            synchronized (this) {
8867                // Since we lost lock on task, make sure it is still there.
8868                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8869                if (task != null) {
8870                    if (!isSystemInitiated
8871                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8872                        throw new IllegalArgumentException("Invalid task, not in foreground");
8873                    }
8874                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8875                }
8876            }
8877        } finally {
8878            Binder.restoreCallingIdentity(ident);
8879        }
8880    }
8881
8882    @Override
8883    public void startLockTaskMode(int taskId) {
8884        final TaskRecord task;
8885        long ident = Binder.clearCallingIdentity();
8886        try {
8887            synchronized (this) {
8888                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8889            }
8890        } finally {
8891            Binder.restoreCallingIdentity(ident);
8892        }
8893        if (task != null) {
8894            startLockTaskMode(task);
8895        }
8896    }
8897
8898    @Override
8899    public void startLockTaskMode(IBinder token) {
8900        final TaskRecord task;
8901        long ident = Binder.clearCallingIdentity();
8902        try {
8903            synchronized (this) {
8904                final ActivityRecord r = ActivityRecord.forToken(token);
8905                if (r == null) {
8906                    return;
8907                }
8908                task = r.task;
8909            }
8910        } finally {
8911            Binder.restoreCallingIdentity(ident);
8912        }
8913        if (task != null) {
8914            startLockTaskMode(task);
8915        }
8916    }
8917
8918    @Override
8919    public void startLockTaskModeOnCurrent() throws RemoteException {
8920        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8921                "startLockTaskModeOnCurrent");
8922        ActivityRecord r = null;
8923        synchronized (this) {
8924            r = mStackSupervisor.topRunningActivityLocked();
8925        }
8926        startLockTaskMode(r.task);
8927    }
8928
8929    @Override
8930    public void stopLockTaskMode() {
8931        // Verify that the user matches the package of the intent for the TaskRecord
8932        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8933        // and stopLockTaskMode.
8934        final int callingUid = Binder.getCallingUid();
8935        if (callingUid != Process.SYSTEM_UID) {
8936            try {
8937                String pkg =
8938                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8939                int uid = mContext.getPackageManager().getPackageUid(pkg,
8940                        Binder.getCallingUserHandle().getIdentifier());
8941                if (uid != callingUid) {
8942                    throw new SecurityException("Invalid uid, expected " + uid);
8943                }
8944            } catch (NameNotFoundException e) {
8945                Log.d(TAG, "stopLockTaskMode " + e);
8946                return;
8947            }
8948        }
8949        long ident = Binder.clearCallingIdentity();
8950        try {
8951            Log.d(TAG, "stopLockTaskMode");
8952            // Stop lock task
8953            synchronized (this) {
8954                mStackSupervisor.setLockTaskModeLocked(null, false);
8955            }
8956        } finally {
8957            Binder.restoreCallingIdentity(ident);
8958        }
8959    }
8960
8961    @Override
8962    public void stopLockTaskModeOnCurrent() throws RemoteException {
8963        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8964                "stopLockTaskModeOnCurrent");
8965        long ident = Binder.clearCallingIdentity();
8966        try {
8967            stopLockTaskMode();
8968        } finally {
8969            Binder.restoreCallingIdentity(ident);
8970        }
8971    }
8972
8973    @Override
8974    public boolean isInLockTaskMode() {
8975        synchronized (this) {
8976            return mStackSupervisor.isInLockTaskMode();
8977        }
8978    }
8979
8980    // =========================================================
8981    // CONTENT PROVIDERS
8982    // =========================================================
8983
8984    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8985        List<ProviderInfo> providers = null;
8986        try {
8987            providers = AppGlobals.getPackageManager().
8988                queryContentProviders(app.processName, app.uid,
8989                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8990        } catch (RemoteException ex) {
8991        }
8992        if (DEBUG_MU)
8993            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8994        int userId = app.userId;
8995        if (providers != null) {
8996            int N = providers.size();
8997            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8998            for (int i=0; i<N; i++) {
8999                ProviderInfo cpi =
9000                    (ProviderInfo)providers.get(i);
9001                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9002                        cpi.name, cpi.flags);
9003                if (singleton && UserHandle.getUserId(app.uid) != 0) {
9004                    // This is a singleton provider, but a user besides the
9005                    // default user is asking to initialize a process it runs
9006                    // in...  well, no, it doesn't actually run in this process,
9007                    // it runs in the process of the default user.  Get rid of it.
9008                    providers.remove(i);
9009                    N--;
9010                    i--;
9011                    continue;
9012                }
9013
9014                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9015                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9016                if (cpr == null) {
9017                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9018                    mProviderMap.putProviderByClass(comp, cpr);
9019                }
9020                if (DEBUG_MU)
9021                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9022                app.pubProviders.put(cpi.name, cpr);
9023                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9024                    // Don't add this if it is a platform component that is marked
9025                    // to run in multiple processes, because this is actually
9026                    // part of the framework so doesn't make sense to track as a
9027                    // separate apk in the process.
9028                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9029                            mProcessStats);
9030                }
9031                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9032            }
9033        }
9034        return providers;
9035    }
9036
9037    /**
9038     * Check if {@link ProcessRecord} has a possible chance at accessing the
9039     * given {@link ProviderInfo}. Final permission checking is always done
9040     * in {@link ContentProvider}.
9041     */
9042    private final String checkContentProviderPermissionLocked(
9043            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9044        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9045        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9046        boolean checkedGrants = false;
9047        if (checkUser) {
9048            // Looking for cross-user grants before enforcing the typical cross-users permissions
9049            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9050            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9051                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9052                    return null;
9053                }
9054                checkedGrants = true;
9055            }
9056            userId = handleIncomingUser(callingPid, callingUid, userId,
9057                    false, ALLOW_NON_FULL,
9058                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9059            if (userId != tmpTargetUserId) {
9060                // When we actually went to determine the final targer user ID, this ended
9061                // up different than our initial check for the authority.  This is because
9062                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9063                // SELF.  So we need to re-check the grants again.
9064                checkedGrants = false;
9065            }
9066        }
9067        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9068                cpi.applicationInfo.uid, cpi.exported)
9069                == PackageManager.PERMISSION_GRANTED) {
9070            return null;
9071        }
9072        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9073                cpi.applicationInfo.uid, cpi.exported)
9074                == PackageManager.PERMISSION_GRANTED) {
9075            return null;
9076        }
9077
9078        PathPermission[] pps = cpi.pathPermissions;
9079        if (pps != null) {
9080            int i = pps.length;
9081            while (i > 0) {
9082                i--;
9083                PathPermission pp = pps[i];
9084                String pprperm = pp.getReadPermission();
9085                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9086                        cpi.applicationInfo.uid, cpi.exported)
9087                        == PackageManager.PERMISSION_GRANTED) {
9088                    return null;
9089                }
9090                String ppwperm = pp.getWritePermission();
9091                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9092                        cpi.applicationInfo.uid, cpi.exported)
9093                        == PackageManager.PERMISSION_GRANTED) {
9094                    return null;
9095                }
9096            }
9097        }
9098        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9099            return null;
9100        }
9101
9102        String msg;
9103        if (!cpi.exported) {
9104            msg = "Permission Denial: opening provider " + cpi.name
9105                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9106                    + ", uid=" + callingUid + ") that is not exported from uid "
9107                    + cpi.applicationInfo.uid;
9108        } else {
9109            msg = "Permission Denial: opening provider " + cpi.name
9110                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9111                    + ", uid=" + callingUid + ") requires "
9112                    + cpi.readPermission + " or " + cpi.writePermission;
9113        }
9114        Slog.w(TAG, msg);
9115        return msg;
9116    }
9117
9118    /**
9119     * Returns if the ContentProvider has granted a uri to callingUid
9120     */
9121    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9122        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9123        if (perms != null) {
9124            for (int i=perms.size()-1; i>=0; i--) {
9125                GrantUri grantUri = perms.keyAt(i);
9126                if (grantUri.sourceUserId == userId || !checkUser) {
9127                    if (matchesProvider(grantUri.uri, cpi)) {
9128                        return true;
9129                    }
9130                }
9131            }
9132        }
9133        return false;
9134    }
9135
9136    /**
9137     * Returns true if the uri authority is one of the authorities specified in the provider.
9138     */
9139    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9140        String uriAuth = uri.getAuthority();
9141        String cpiAuth = cpi.authority;
9142        if (cpiAuth.indexOf(';') == -1) {
9143            return cpiAuth.equals(uriAuth);
9144        }
9145        String[] cpiAuths = cpiAuth.split(";");
9146        int length = cpiAuths.length;
9147        for (int i = 0; i < length; i++) {
9148            if (cpiAuths[i].equals(uriAuth)) return true;
9149        }
9150        return false;
9151    }
9152
9153    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9154            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9155        if (r != null) {
9156            for (int i=0; i<r.conProviders.size(); i++) {
9157                ContentProviderConnection conn = r.conProviders.get(i);
9158                if (conn.provider == cpr) {
9159                    if (DEBUG_PROVIDER) Slog.v(TAG,
9160                            "Adding provider requested by "
9161                            + r.processName + " from process "
9162                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9163                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9164                    if (stable) {
9165                        conn.stableCount++;
9166                        conn.numStableIncs++;
9167                    } else {
9168                        conn.unstableCount++;
9169                        conn.numUnstableIncs++;
9170                    }
9171                    return conn;
9172                }
9173            }
9174            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9175            if (stable) {
9176                conn.stableCount = 1;
9177                conn.numStableIncs = 1;
9178            } else {
9179                conn.unstableCount = 1;
9180                conn.numUnstableIncs = 1;
9181            }
9182            cpr.connections.add(conn);
9183            r.conProviders.add(conn);
9184            return conn;
9185        }
9186        cpr.addExternalProcessHandleLocked(externalProcessToken);
9187        return null;
9188    }
9189
9190    boolean decProviderCountLocked(ContentProviderConnection conn,
9191            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9192        if (conn != null) {
9193            cpr = conn.provider;
9194            if (DEBUG_PROVIDER) Slog.v(TAG,
9195                    "Removing provider requested by "
9196                    + conn.client.processName + " from process "
9197                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9198                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9199            if (stable) {
9200                conn.stableCount--;
9201            } else {
9202                conn.unstableCount--;
9203            }
9204            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9205                cpr.connections.remove(conn);
9206                conn.client.conProviders.remove(conn);
9207                return true;
9208            }
9209            return false;
9210        }
9211        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9212        return false;
9213    }
9214
9215    private void checkTime(long startTime, String where) {
9216        long now = SystemClock.elapsedRealtime();
9217        if ((now-startTime) > 1000) {
9218            // If we are taking more than a second, log about it.
9219            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9220        }
9221    }
9222
9223    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9224            String name, IBinder token, boolean stable, int userId) {
9225        ContentProviderRecord cpr;
9226        ContentProviderConnection conn = null;
9227        ProviderInfo cpi = null;
9228
9229        synchronized(this) {
9230            long startTime = SystemClock.elapsedRealtime();
9231
9232            ProcessRecord r = null;
9233            if (caller != null) {
9234                r = getRecordForAppLocked(caller);
9235                if (r == null) {
9236                    throw new SecurityException(
9237                            "Unable to find app for caller " + caller
9238                          + " (pid=" + Binder.getCallingPid()
9239                          + ") when getting content provider " + name);
9240                }
9241            }
9242
9243            boolean checkCrossUser = true;
9244
9245            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9246
9247            // First check if this content provider has been published...
9248            cpr = mProviderMap.getProviderByName(name, userId);
9249            // If that didn't work, check if it exists for user 0 and then
9250            // verify that it's a singleton provider before using it.
9251            if (cpr == null && userId != UserHandle.USER_OWNER) {
9252                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9253                if (cpr != null) {
9254                    cpi = cpr.info;
9255                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9256                            cpi.name, cpi.flags)
9257                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9258                        userId = UserHandle.USER_OWNER;
9259                        checkCrossUser = false;
9260                    } else {
9261                        cpr = null;
9262                        cpi = null;
9263                    }
9264                }
9265            }
9266
9267            boolean providerRunning = cpr != null;
9268            if (providerRunning) {
9269                cpi = cpr.info;
9270                String msg;
9271                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9272                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9273                        != null) {
9274                    throw new SecurityException(msg);
9275                }
9276                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9277
9278                if (r != null && cpr.canRunHere(r)) {
9279                    // This provider has been published or is in the process
9280                    // of being published...  but it is also allowed to run
9281                    // in the caller's process, so don't make a connection
9282                    // and just let the caller instantiate its own instance.
9283                    ContentProviderHolder holder = cpr.newHolder(null);
9284                    // don't give caller the provider object, it needs
9285                    // to make its own.
9286                    holder.provider = null;
9287                    return holder;
9288                }
9289
9290                final long origId = Binder.clearCallingIdentity();
9291
9292                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9293
9294                // In this case the provider instance already exists, so we can
9295                // return it right away.
9296                conn = incProviderCountLocked(r, cpr, token, stable);
9297                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9298                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9299                        // If this is a perceptible app accessing the provider,
9300                        // make sure to count it as being accessed and thus
9301                        // back up on the LRU list.  This is good because
9302                        // content providers are often expensive to start.
9303                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9304                        updateLruProcessLocked(cpr.proc, false, null);
9305                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9306                    }
9307                }
9308
9309                if (cpr.proc != null) {
9310                    if (false) {
9311                        if (cpr.name.flattenToShortString().equals(
9312                                "com.android.providers.calendar/.CalendarProvider2")) {
9313                            Slog.v(TAG, "****************** KILLING "
9314                                + cpr.name.flattenToShortString());
9315                            Process.killProcess(cpr.proc.pid);
9316                        }
9317                    }
9318                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9319                    boolean success = updateOomAdjLocked(cpr.proc);
9320                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9321                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9322                    // NOTE: there is still a race here where a signal could be
9323                    // pending on the process even though we managed to update its
9324                    // adj level.  Not sure what to do about this, but at least
9325                    // the race is now smaller.
9326                    if (!success) {
9327                        // Uh oh...  it looks like the provider's process
9328                        // has been killed on us.  We need to wait for a new
9329                        // process to be started, and make sure its death
9330                        // doesn't kill our process.
9331                        Slog.i(TAG,
9332                                "Existing provider " + cpr.name.flattenToShortString()
9333                                + " is crashing; detaching " + r);
9334                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9335                        checkTime(startTime, "getContentProviderImpl: before appDied");
9336                        appDiedLocked(cpr.proc);
9337                        checkTime(startTime, "getContentProviderImpl: after appDied");
9338                        if (!lastRef) {
9339                            // This wasn't the last ref our process had on
9340                            // the provider...  we have now been killed, bail.
9341                            return null;
9342                        }
9343                        providerRunning = false;
9344                        conn = null;
9345                    }
9346                }
9347
9348                Binder.restoreCallingIdentity(origId);
9349            }
9350
9351            boolean singleton;
9352            if (!providerRunning) {
9353                try {
9354                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9355                    cpi = AppGlobals.getPackageManager().
9356                        resolveContentProvider(name,
9357                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9358                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9359                } catch (RemoteException ex) {
9360                }
9361                if (cpi == null) {
9362                    return null;
9363                }
9364                // If the provider is a singleton AND
9365                // (it's a call within the same user || the provider is a
9366                // privileged app)
9367                // Then allow connecting to the singleton provider
9368                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9369                        cpi.name, cpi.flags)
9370                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9371                if (singleton) {
9372                    userId = UserHandle.USER_OWNER;
9373                }
9374                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9375                checkTime(startTime, "getContentProviderImpl: got app info for user");
9376
9377                String msg;
9378                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9379                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9380                        != null) {
9381                    throw new SecurityException(msg);
9382                }
9383                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9384
9385                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9386                        && !cpi.processName.equals("system")) {
9387                    // If this content provider does not run in the system
9388                    // process, and the system is not yet ready to run other
9389                    // processes, then fail fast instead of hanging.
9390                    throw new IllegalArgumentException(
9391                            "Attempt to launch content provider before system ready");
9392                }
9393
9394                // Make sure that the user who owns this provider is started.  If not,
9395                // we don't want to allow it to run.
9396                if (mStartedUsers.get(userId) == null) {
9397                    Slog.w(TAG, "Unable to launch app "
9398                            + cpi.applicationInfo.packageName + "/"
9399                            + cpi.applicationInfo.uid + " for provider "
9400                            + name + ": user " + userId + " is stopped");
9401                    return null;
9402                }
9403
9404                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9405                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9406                cpr = mProviderMap.getProviderByClass(comp, userId);
9407                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9408                final boolean firstClass = cpr == null;
9409                if (firstClass) {
9410                    final long ident = Binder.clearCallingIdentity();
9411                    try {
9412                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9413                        ApplicationInfo ai =
9414                            AppGlobals.getPackageManager().
9415                                getApplicationInfo(
9416                                        cpi.applicationInfo.packageName,
9417                                        STOCK_PM_FLAGS, userId);
9418                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9419                        if (ai == null) {
9420                            Slog.w(TAG, "No package info for content provider "
9421                                    + cpi.name);
9422                            return null;
9423                        }
9424                        ai = getAppInfoForUser(ai, userId);
9425                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9426                    } catch (RemoteException ex) {
9427                        // pm is in same process, this will never happen.
9428                    } finally {
9429                        Binder.restoreCallingIdentity(ident);
9430                    }
9431                }
9432
9433                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9434
9435                if (r != null && cpr.canRunHere(r)) {
9436                    // If this is a multiprocess provider, then just return its
9437                    // info and allow the caller to instantiate it.  Only do
9438                    // this if the provider is the same user as the caller's
9439                    // process, or can run as root (so can be in any process).
9440                    return cpr.newHolder(null);
9441                }
9442
9443                if (DEBUG_PROVIDER) {
9444                    RuntimeException e = new RuntimeException("here");
9445                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9446                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9447                }
9448
9449                // This is single process, and our app is now connecting to it.
9450                // See if we are already in the process of launching this
9451                // provider.
9452                final int N = mLaunchingProviders.size();
9453                int i;
9454                for (i=0; i<N; i++) {
9455                    if (mLaunchingProviders.get(i) == cpr) {
9456                        break;
9457                    }
9458                }
9459
9460                // If the provider is not already being launched, then get it
9461                // started.
9462                if (i >= N) {
9463                    final long origId = Binder.clearCallingIdentity();
9464
9465                    try {
9466                        // Content provider is now in use, its package can't be stopped.
9467                        try {
9468                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9469                            AppGlobals.getPackageManager().setPackageStoppedState(
9470                                    cpr.appInfo.packageName, false, userId);
9471                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9472                        } catch (RemoteException e) {
9473                        } catch (IllegalArgumentException e) {
9474                            Slog.w(TAG, "Failed trying to unstop package "
9475                                    + cpr.appInfo.packageName + ": " + e);
9476                        }
9477
9478                        // Use existing process if already started
9479                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9480                        ProcessRecord proc = getProcessRecordLocked(
9481                                cpi.processName, cpr.appInfo.uid, false);
9482                        if (proc != null && proc.thread != null) {
9483                            if (DEBUG_PROVIDER) {
9484                                Slog.d(TAG, "Installing in existing process " + proc);
9485                            }
9486                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9487                            proc.pubProviders.put(cpi.name, cpr);
9488                            try {
9489                                proc.thread.scheduleInstallProvider(cpi);
9490                            } catch (RemoteException e) {
9491                            }
9492                        } else {
9493                            checkTime(startTime, "getContentProviderImpl: before start process");
9494                            proc = startProcessLocked(cpi.processName,
9495                                    cpr.appInfo, false, 0, "content provider",
9496                                    new ComponentName(cpi.applicationInfo.packageName,
9497                                            cpi.name), false, false, false);
9498                            checkTime(startTime, "getContentProviderImpl: after start process");
9499                            if (proc == null) {
9500                                Slog.w(TAG, "Unable to launch app "
9501                                        + cpi.applicationInfo.packageName + "/"
9502                                        + cpi.applicationInfo.uid + " for provider "
9503                                        + name + ": process is bad");
9504                                return null;
9505                            }
9506                        }
9507                        cpr.launchingApp = proc;
9508                        mLaunchingProviders.add(cpr);
9509                    } finally {
9510                        Binder.restoreCallingIdentity(origId);
9511                    }
9512                }
9513
9514                checkTime(startTime, "getContentProviderImpl: updating data structures");
9515
9516                // Make sure the provider is published (the same provider class
9517                // may be published under multiple names).
9518                if (firstClass) {
9519                    mProviderMap.putProviderByClass(comp, cpr);
9520                }
9521
9522                mProviderMap.putProviderByName(name, cpr);
9523                conn = incProviderCountLocked(r, cpr, token, stable);
9524                if (conn != null) {
9525                    conn.waiting = true;
9526                }
9527            }
9528            checkTime(startTime, "getContentProviderImpl: done!");
9529        }
9530
9531        // Wait for the provider to be published...
9532        synchronized (cpr) {
9533            while (cpr.provider == null) {
9534                if (cpr.launchingApp == null) {
9535                    Slog.w(TAG, "Unable to launch app "
9536                            + cpi.applicationInfo.packageName + "/"
9537                            + cpi.applicationInfo.uid + " for provider "
9538                            + name + ": launching app became null");
9539                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9540                            UserHandle.getUserId(cpi.applicationInfo.uid),
9541                            cpi.applicationInfo.packageName,
9542                            cpi.applicationInfo.uid, name);
9543                    return null;
9544                }
9545                try {
9546                    if (DEBUG_MU) {
9547                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9548                                + cpr.launchingApp);
9549                    }
9550                    if (conn != null) {
9551                        conn.waiting = true;
9552                    }
9553                    cpr.wait();
9554                } catch (InterruptedException ex) {
9555                } finally {
9556                    if (conn != null) {
9557                        conn.waiting = false;
9558                    }
9559                }
9560            }
9561        }
9562        return cpr != null ? cpr.newHolder(conn) : null;
9563    }
9564
9565    @Override
9566    public final ContentProviderHolder getContentProvider(
9567            IApplicationThread caller, String name, int userId, boolean stable) {
9568        enforceNotIsolatedCaller("getContentProvider");
9569        if (caller == null) {
9570            String msg = "null IApplicationThread when getting content provider "
9571                    + name;
9572            Slog.w(TAG, msg);
9573            throw new SecurityException(msg);
9574        }
9575        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9576        // with cross-user grant.
9577        return getContentProviderImpl(caller, name, null, stable, userId);
9578    }
9579
9580    public ContentProviderHolder getContentProviderExternal(
9581            String name, int userId, IBinder token) {
9582        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9583            "Do not have permission in call getContentProviderExternal()");
9584        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9585                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9586        return getContentProviderExternalUnchecked(name, token, userId);
9587    }
9588
9589    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9590            IBinder token, int userId) {
9591        return getContentProviderImpl(null, name, token, true, userId);
9592    }
9593
9594    /**
9595     * Drop a content provider from a ProcessRecord's bookkeeping
9596     */
9597    public void removeContentProvider(IBinder connection, boolean stable) {
9598        enforceNotIsolatedCaller("removeContentProvider");
9599        long ident = Binder.clearCallingIdentity();
9600        try {
9601            synchronized (this) {
9602                ContentProviderConnection conn;
9603                try {
9604                    conn = (ContentProviderConnection)connection;
9605                } catch (ClassCastException e) {
9606                    String msg ="removeContentProvider: " + connection
9607                            + " not a ContentProviderConnection";
9608                    Slog.w(TAG, msg);
9609                    throw new IllegalArgumentException(msg);
9610                }
9611                if (conn == null) {
9612                    throw new NullPointerException("connection is null");
9613                }
9614                if (decProviderCountLocked(conn, null, null, stable)) {
9615                    updateOomAdjLocked();
9616                }
9617            }
9618        } finally {
9619            Binder.restoreCallingIdentity(ident);
9620        }
9621    }
9622
9623    public void removeContentProviderExternal(String name, IBinder token) {
9624        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9625            "Do not have permission in call removeContentProviderExternal()");
9626        int userId = UserHandle.getCallingUserId();
9627        long ident = Binder.clearCallingIdentity();
9628        try {
9629            removeContentProviderExternalUnchecked(name, token, userId);
9630        } finally {
9631            Binder.restoreCallingIdentity(ident);
9632        }
9633    }
9634
9635    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9636        synchronized (this) {
9637            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9638            if(cpr == null) {
9639                //remove from mProvidersByClass
9640                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9641                return;
9642            }
9643
9644            //update content provider record entry info
9645            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9646            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9647            if (localCpr.hasExternalProcessHandles()) {
9648                if (localCpr.removeExternalProcessHandleLocked(token)) {
9649                    updateOomAdjLocked();
9650                } else {
9651                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9652                            + " with no external reference for token: "
9653                            + token + ".");
9654                }
9655            } else {
9656                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9657                        + " with no external references.");
9658            }
9659        }
9660    }
9661
9662    public final void publishContentProviders(IApplicationThread caller,
9663            List<ContentProviderHolder> providers) {
9664        if (providers == null) {
9665            return;
9666        }
9667
9668        enforceNotIsolatedCaller("publishContentProviders");
9669        synchronized (this) {
9670            final ProcessRecord r = getRecordForAppLocked(caller);
9671            if (DEBUG_MU)
9672                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9673            if (r == null) {
9674                throw new SecurityException(
9675                        "Unable to find app for caller " + caller
9676                      + " (pid=" + Binder.getCallingPid()
9677                      + ") when publishing content providers");
9678            }
9679
9680            final long origId = Binder.clearCallingIdentity();
9681
9682            final int N = providers.size();
9683            for (int i=0; i<N; i++) {
9684                ContentProviderHolder src = providers.get(i);
9685                if (src == null || src.info == null || src.provider == null) {
9686                    continue;
9687                }
9688                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9689                if (DEBUG_MU)
9690                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9691                if (dst != null) {
9692                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9693                    mProviderMap.putProviderByClass(comp, dst);
9694                    String names[] = dst.info.authority.split(";");
9695                    for (int j = 0; j < names.length; j++) {
9696                        mProviderMap.putProviderByName(names[j], dst);
9697                    }
9698
9699                    int NL = mLaunchingProviders.size();
9700                    int j;
9701                    for (j=0; j<NL; j++) {
9702                        if (mLaunchingProviders.get(j) == dst) {
9703                            mLaunchingProviders.remove(j);
9704                            j--;
9705                            NL--;
9706                        }
9707                    }
9708                    synchronized (dst) {
9709                        dst.provider = src.provider;
9710                        dst.proc = r;
9711                        dst.notifyAll();
9712                    }
9713                    updateOomAdjLocked(r);
9714                }
9715            }
9716
9717            Binder.restoreCallingIdentity(origId);
9718        }
9719    }
9720
9721    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9722        ContentProviderConnection conn;
9723        try {
9724            conn = (ContentProviderConnection)connection;
9725        } catch (ClassCastException e) {
9726            String msg ="refContentProvider: " + connection
9727                    + " not a ContentProviderConnection";
9728            Slog.w(TAG, msg);
9729            throw new IllegalArgumentException(msg);
9730        }
9731        if (conn == null) {
9732            throw new NullPointerException("connection is null");
9733        }
9734
9735        synchronized (this) {
9736            if (stable > 0) {
9737                conn.numStableIncs += stable;
9738            }
9739            stable = conn.stableCount + stable;
9740            if (stable < 0) {
9741                throw new IllegalStateException("stableCount < 0: " + stable);
9742            }
9743
9744            if (unstable > 0) {
9745                conn.numUnstableIncs += unstable;
9746            }
9747            unstable = conn.unstableCount + unstable;
9748            if (unstable < 0) {
9749                throw new IllegalStateException("unstableCount < 0: " + unstable);
9750            }
9751
9752            if ((stable+unstable) <= 0) {
9753                throw new IllegalStateException("ref counts can't go to zero here: stable="
9754                        + stable + " unstable=" + unstable);
9755            }
9756            conn.stableCount = stable;
9757            conn.unstableCount = unstable;
9758            return !conn.dead;
9759        }
9760    }
9761
9762    public void unstableProviderDied(IBinder connection) {
9763        ContentProviderConnection conn;
9764        try {
9765            conn = (ContentProviderConnection)connection;
9766        } catch (ClassCastException e) {
9767            String msg ="refContentProvider: " + connection
9768                    + " not a ContentProviderConnection";
9769            Slog.w(TAG, msg);
9770            throw new IllegalArgumentException(msg);
9771        }
9772        if (conn == null) {
9773            throw new NullPointerException("connection is null");
9774        }
9775
9776        // Safely retrieve the content provider associated with the connection.
9777        IContentProvider provider;
9778        synchronized (this) {
9779            provider = conn.provider.provider;
9780        }
9781
9782        if (provider == null) {
9783            // Um, yeah, we're way ahead of you.
9784            return;
9785        }
9786
9787        // Make sure the caller is being honest with us.
9788        if (provider.asBinder().pingBinder()) {
9789            // Er, no, still looks good to us.
9790            synchronized (this) {
9791                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9792                        + " says " + conn + " died, but we don't agree");
9793                return;
9794            }
9795        }
9796
9797        // Well look at that!  It's dead!
9798        synchronized (this) {
9799            if (conn.provider.provider != provider) {
9800                // But something changed...  good enough.
9801                return;
9802            }
9803
9804            ProcessRecord proc = conn.provider.proc;
9805            if (proc == null || proc.thread == null) {
9806                // Seems like the process is already cleaned up.
9807                return;
9808            }
9809
9810            // As far as we're concerned, this is just like receiving a
9811            // death notification...  just a bit prematurely.
9812            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9813                    + ") early provider death");
9814            final long ident = Binder.clearCallingIdentity();
9815            try {
9816                appDiedLocked(proc);
9817            } finally {
9818                Binder.restoreCallingIdentity(ident);
9819            }
9820        }
9821    }
9822
9823    @Override
9824    public void appNotRespondingViaProvider(IBinder connection) {
9825        enforceCallingPermission(
9826                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9827
9828        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9829        if (conn == null) {
9830            Slog.w(TAG, "ContentProviderConnection is null");
9831            return;
9832        }
9833
9834        final ProcessRecord host = conn.provider.proc;
9835        if (host == null) {
9836            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9837            return;
9838        }
9839
9840        final long token = Binder.clearCallingIdentity();
9841        try {
9842            appNotResponding(host, null, null, false, "ContentProvider not responding");
9843        } finally {
9844            Binder.restoreCallingIdentity(token);
9845        }
9846    }
9847
9848    public final void installSystemProviders() {
9849        List<ProviderInfo> providers;
9850        synchronized (this) {
9851            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9852            providers = generateApplicationProvidersLocked(app);
9853            if (providers != null) {
9854                for (int i=providers.size()-1; i>=0; i--) {
9855                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9856                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9857                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9858                                + ": not system .apk");
9859                        providers.remove(i);
9860                    }
9861                }
9862            }
9863        }
9864        if (providers != null) {
9865            mSystemThread.installSystemProviders(providers);
9866        }
9867
9868        mCoreSettingsObserver = new CoreSettingsObserver(this);
9869
9870        //mUsageStatsService.monitorPackages();
9871    }
9872
9873    /**
9874     * Allows apps to retrieve the MIME type of a URI.
9875     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9876     * users, then it does not need permission to access the ContentProvider.
9877     * Either, it needs cross-user uri grants.
9878     *
9879     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9880     *
9881     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9882     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9883     */
9884    public String getProviderMimeType(Uri uri, int userId) {
9885        enforceNotIsolatedCaller("getProviderMimeType");
9886        final String name = uri.getAuthority();
9887        int callingUid = Binder.getCallingUid();
9888        int callingPid = Binder.getCallingPid();
9889        long ident = 0;
9890        boolean clearedIdentity = false;
9891        userId = unsafeConvertIncomingUser(userId);
9892        if (canClearIdentity(callingPid, callingUid, userId)) {
9893            clearedIdentity = true;
9894            ident = Binder.clearCallingIdentity();
9895        }
9896        ContentProviderHolder holder = null;
9897        try {
9898            holder = getContentProviderExternalUnchecked(name, null, userId);
9899            if (holder != null) {
9900                return holder.provider.getType(uri);
9901            }
9902        } catch (RemoteException e) {
9903            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9904            return null;
9905        } finally {
9906            // We need to clear the identity to call removeContentProviderExternalUnchecked
9907            if (!clearedIdentity) {
9908                ident = Binder.clearCallingIdentity();
9909            }
9910            try {
9911                if (holder != null) {
9912                    removeContentProviderExternalUnchecked(name, null, userId);
9913                }
9914            } finally {
9915                Binder.restoreCallingIdentity(ident);
9916            }
9917        }
9918
9919        return null;
9920    }
9921
9922    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9923        if (UserHandle.getUserId(callingUid) == userId) {
9924            return true;
9925        }
9926        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9927                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9928                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9929                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9930                return true;
9931        }
9932        return false;
9933    }
9934
9935    // =========================================================
9936    // GLOBAL MANAGEMENT
9937    // =========================================================
9938
9939    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9940            boolean isolated, int isolatedUid) {
9941        String proc = customProcess != null ? customProcess : info.processName;
9942        BatteryStatsImpl.Uid.Proc ps = null;
9943        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9944        int uid = info.uid;
9945        if (isolated) {
9946            if (isolatedUid == 0) {
9947                int userId = UserHandle.getUserId(uid);
9948                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9949                while (true) {
9950                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9951                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9952                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9953                    }
9954                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9955                    mNextIsolatedProcessUid++;
9956                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9957                        // No process for this uid, use it.
9958                        break;
9959                    }
9960                    stepsLeft--;
9961                    if (stepsLeft <= 0) {
9962                        return null;
9963                    }
9964                }
9965            } else {
9966                // Special case for startIsolatedProcess (internal only), where
9967                // the uid of the isolated process is specified by the caller.
9968                uid = isolatedUid;
9969            }
9970        }
9971        return new ProcessRecord(stats, info, proc, uid);
9972    }
9973
9974    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9975            String abiOverride) {
9976        ProcessRecord app;
9977        if (!isolated) {
9978            app = getProcessRecordLocked(info.processName, info.uid, true);
9979        } else {
9980            app = null;
9981        }
9982
9983        if (app == null) {
9984            app = newProcessRecordLocked(info, null, isolated, 0);
9985            mProcessNames.put(info.processName, app.uid, app);
9986            if (isolated) {
9987                mIsolatedProcesses.put(app.uid, app);
9988            }
9989            updateLruProcessLocked(app, false, null);
9990            updateOomAdjLocked();
9991        }
9992
9993        // This package really, really can not be stopped.
9994        try {
9995            AppGlobals.getPackageManager().setPackageStoppedState(
9996                    info.packageName, false, UserHandle.getUserId(app.uid));
9997        } catch (RemoteException e) {
9998        } catch (IllegalArgumentException e) {
9999            Slog.w(TAG, "Failed trying to unstop package "
10000                    + info.packageName + ": " + e);
10001        }
10002
10003        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
10004                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
10005            app.persistent = true;
10006            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10007        }
10008        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10009            mPersistentStartingProcesses.add(app);
10010            startProcessLocked(app, "added application", app.processName, abiOverride,
10011                    null /* entryPoint */, null /* entryPointArgs */);
10012        }
10013
10014        return app;
10015    }
10016
10017    public void unhandledBack() {
10018        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10019                "unhandledBack()");
10020
10021        synchronized(this) {
10022            final long origId = Binder.clearCallingIdentity();
10023            try {
10024                getFocusedStack().unhandledBackLocked();
10025            } finally {
10026                Binder.restoreCallingIdentity(origId);
10027            }
10028        }
10029    }
10030
10031    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10032        enforceNotIsolatedCaller("openContentUri");
10033        final int userId = UserHandle.getCallingUserId();
10034        String name = uri.getAuthority();
10035        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10036        ParcelFileDescriptor pfd = null;
10037        if (cph != null) {
10038            // We record the binder invoker's uid in thread-local storage before
10039            // going to the content provider to open the file.  Later, in the code
10040            // that handles all permissions checks, we look for this uid and use
10041            // that rather than the Activity Manager's own uid.  The effect is that
10042            // we do the check against the caller's permissions even though it looks
10043            // to the content provider like the Activity Manager itself is making
10044            // the request.
10045            sCallerIdentity.set(new Identity(
10046                    Binder.getCallingPid(), Binder.getCallingUid()));
10047            try {
10048                pfd = cph.provider.openFile(null, uri, "r", null);
10049            } catch (FileNotFoundException e) {
10050                // do nothing; pfd will be returned null
10051            } finally {
10052                // Ensure that whatever happens, we clean up the identity state
10053                sCallerIdentity.remove();
10054            }
10055
10056            // We've got the fd now, so we're done with the provider.
10057            removeContentProviderExternalUnchecked(name, null, userId);
10058        } else {
10059            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10060        }
10061        return pfd;
10062    }
10063
10064    // Actually is sleeping or shutting down or whatever else in the future
10065    // is an inactive state.
10066    public boolean isSleepingOrShuttingDown() {
10067        return isSleeping() || mShuttingDown;
10068    }
10069
10070    public boolean isSleeping() {
10071        return mSleeping;
10072    }
10073
10074    void goingToSleep() {
10075        synchronized(this) {
10076            mWentToSleep = true;
10077            goToSleepIfNeededLocked();
10078        }
10079    }
10080
10081    void finishRunningVoiceLocked() {
10082        if (mRunningVoice) {
10083            mRunningVoice = false;
10084            goToSleepIfNeededLocked();
10085        }
10086    }
10087
10088    void goToSleepIfNeededLocked() {
10089        if (mWentToSleep && !mRunningVoice) {
10090            if (!mSleeping) {
10091                mSleeping = true;
10092                mStackSupervisor.goingToSleepLocked();
10093
10094                // Initialize the wake times of all processes.
10095                checkExcessivePowerUsageLocked(false);
10096                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10097                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10098                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10099            }
10100        }
10101    }
10102
10103    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10104        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10105            // Never persist the home stack.
10106            return;
10107        }
10108        mTaskPersister.wakeup(task, flush);
10109    }
10110
10111    @Override
10112    public boolean shutdown(int timeout) {
10113        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10114                != PackageManager.PERMISSION_GRANTED) {
10115            throw new SecurityException("Requires permission "
10116                    + android.Manifest.permission.SHUTDOWN);
10117        }
10118
10119        boolean timedout = false;
10120
10121        synchronized(this) {
10122            mShuttingDown = true;
10123            updateEventDispatchingLocked();
10124            timedout = mStackSupervisor.shutdownLocked(timeout);
10125        }
10126
10127        mAppOpsService.shutdown();
10128        if (mUsageStatsService != null) {
10129            mUsageStatsService.prepareShutdown();
10130        }
10131        mBatteryStatsService.shutdown();
10132        synchronized (this) {
10133            mProcessStats.shutdownLocked();
10134        }
10135        notifyTaskPersisterLocked(null, true);
10136
10137        return timedout;
10138    }
10139
10140    public final void activitySlept(IBinder token) {
10141        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10142
10143        final long origId = Binder.clearCallingIdentity();
10144
10145        synchronized (this) {
10146            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10147            if (r != null) {
10148                mStackSupervisor.activitySleptLocked(r);
10149            }
10150        }
10151
10152        Binder.restoreCallingIdentity(origId);
10153    }
10154
10155    void logLockScreen(String msg) {
10156        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10157                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10158                mWentToSleep + " mSleeping=" + mSleeping);
10159    }
10160
10161    private void comeOutOfSleepIfNeededLocked() {
10162        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10163            if (mSleeping) {
10164                mSleeping = false;
10165                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10166            }
10167        }
10168    }
10169
10170    void wakingUp() {
10171        synchronized(this) {
10172            mWentToSleep = false;
10173            comeOutOfSleepIfNeededLocked();
10174        }
10175    }
10176
10177    void startRunningVoiceLocked() {
10178        if (!mRunningVoice) {
10179            mRunningVoice = true;
10180            comeOutOfSleepIfNeededLocked();
10181        }
10182    }
10183
10184    private void updateEventDispatchingLocked() {
10185        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10186    }
10187
10188    public void setLockScreenShown(boolean shown) {
10189        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10190                != PackageManager.PERMISSION_GRANTED) {
10191            throw new SecurityException("Requires permission "
10192                    + android.Manifest.permission.DEVICE_POWER);
10193        }
10194
10195        synchronized(this) {
10196            long ident = Binder.clearCallingIdentity();
10197            try {
10198                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10199                mLockScreenShown = shown;
10200                comeOutOfSleepIfNeededLocked();
10201            } finally {
10202                Binder.restoreCallingIdentity(ident);
10203            }
10204        }
10205    }
10206
10207    @Override
10208    public void stopAppSwitches() {
10209        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10210                != PackageManager.PERMISSION_GRANTED) {
10211            throw new SecurityException("Requires permission "
10212                    + android.Manifest.permission.STOP_APP_SWITCHES);
10213        }
10214
10215        synchronized(this) {
10216            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10217                    + APP_SWITCH_DELAY_TIME;
10218            mDidAppSwitch = false;
10219            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10220            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10221            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10222        }
10223    }
10224
10225    public void resumeAppSwitches() {
10226        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10227                != PackageManager.PERMISSION_GRANTED) {
10228            throw new SecurityException("Requires permission "
10229                    + android.Manifest.permission.STOP_APP_SWITCHES);
10230        }
10231
10232        synchronized(this) {
10233            // Note that we don't execute any pending app switches... we will
10234            // let those wait until either the timeout, or the next start
10235            // activity request.
10236            mAppSwitchesAllowedTime = 0;
10237        }
10238    }
10239
10240    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10241            int callingPid, int callingUid, String name) {
10242        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10243            return true;
10244        }
10245
10246        int perm = checkComponentPermission(
10247                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10248                sourceUid, -1, true);
10249        if (perm == PackageManager.PERMISSION_GRANTED) {
10250            return true;
10251        }
10252
10253        // If the actual IPC caller is different from the logical source, then
10254        // also see if they are allowed to control app switches.
10255        if (callingUid != -1 && callingUid != sourceUid) {
10256            perm = checkComponentPermission(
10257                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10258                    callingUid, -1, true);
10259            if (perm == PackageManager.PERMISSION_GRANTED) {
10260                return true;
10261            }
10262        }
10263
10264        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10265        return false;
10266    }
10267
10268    public void setDebugApp(String packageName, boolean waitForDebugger,
10269            boolean persistent) {
10270        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10271                "setDebugApp()");
10272
10273        long ident = Binder.clearCallingIdentity();
10274        try {
10275            // Note that this is not really thread safe if there are multiple
10276            // callers into it at the same time, but that's not a situation we
10277            // care about.
10278            if (persistent) {
10279                final ContentResolver resolver = mContext.getContentResolver();
10280                Settings.Global.putString(
10281                    resolver, Settings.Global.DEBUG_APP,
10282                    packageName);
10283                Settings.Global.putInt(
10284                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10285                    waitForDebugger ? 1 : 0);
10286            }
10287
10288            synchronized (this) {
10289                if (!persistent) {
10290                    mOrigDebugApp = mDebugApp;
10291                    mOrigWaitForDebugger = mWaitForDebugger;
10292                }
10293                mDebugApp = packageName;
10294                mWaitForDebugger = waitForDebugger;
10295                mDebugTransient = !persistent;
10296                if (packageName != null) {
10297                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10298                            false, UserHandle.USER_ALL, "set debug app");
10299                }
10300            }
10301        } finally {
10302            Binder.restoreCallingIdentity(ident);
10303        }
10304    }
10305
10306    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10307        synchronized (this) {
10308            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10309            if (!isDebuggable) {
10310                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10311                    throw new SecurityException("Process not debuggable: " + app.packageName);
10312                }
10313            }
10314
10315            mOpenGlTraceApp = processName;
10316        }
10317    }
10318
10319    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10320        synchronized (this) {
10321            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10322            if (!isDebuggable) {
10323                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10324                    throw new SecurityException("Process not debuggable: " + app.packageName);
10325                }
10326            }
10327            mProfileApp = processName;
10328            mProfileFile = profilerInfo.profileFile;
10329            if (mProfileFd != null) {
10330                try {
10331                    mProfileFd.close();
10332                } catch (IOException e) {
10333                }
10334                mProfileFd = null;
10335            }
10336            mProfileFd = profilerInfo.profileFd;
10337            mSamplingInterval = profilerInfo.samplingInterval;
10338            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10339            mProfileType = 0;
10340        }
10341    }
10342
10343    @Override
10344    public void setAlwaysFinish(boolean enabled) {
10345        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10346                "setAlwaysFinish()");
10347
10348        Settings.Global.putInt(
10349                mContext.getContentResolver(),
10350                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10351
10352        synchronized (this) {
10353            mAlwaysFinishActivities = enabled;
10354        }
10355    }
10356
10357    @Override
10358    public void setActivityController(IActivityController controller) {
10359        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10360                "setActivityController()");
10361        synchronized (this) {
10362            mController = controller;
10363            Watchdog.getInstance().setActivityController(controller);
10364        }
10365    }
10366
10367    @Override
10368    public void setUserIsMonkey(boolean userIsMonkey) {
10369        synchronized (this) {
10370            synchronized (mPidsSelfLocked) {
10371                final int callingPid = Binder.getCallingPid();
10372                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10373                if (precessRecord == null) {
10374                    throw new SecurityException("Unknown process: " + callingPid);
10375                }
10376                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10377                    throw new SecurityException("Only an instrumentation process "
10378                            + "with a UiAutomation can call setUserIsMonkey");
10379                }
10380            }
10381            mUserIsMonkey = userIsMonkey;
10382        }
10383    }
10384
10385    @Override
10386    public boolean isUserAMonkey() {
10387        synchronized (this) {
10388            // If there is a controller also implies the user is a monkey.
10389            return (mUserIsMonkey || mController != null);
10390        }
10391    }
10392
10393    public void requestBugReport() {
10394        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10395        SystemProperties.set("ctl.start", "bugreport");
10396    }
10397
10398    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10399        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10400    }
10401
10402    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10403        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10404            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10405        }
10406        return KEY_DISPATCHING_TIMEOUT;
10407    }
10408
10409    @Override
10410    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10411        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10412                != PackageManager.PERMISSION_GRANTED) {
10413            throw new SecurityException("Requires permission "
10414                    + android.Manifest.permission.FILTER_EVENTS);
10415        }
10416        ProcessRecord proc;
10417        long timeout;
10418        synchronized (this) {
10419            synchronized (mPidsSelfLocked) {
10420                proc = mPidsSelfLocked.get(pid);
10421            }
10422            timeout = getInputDispatchingTimeoutLocked(proc);
10423        }
10424
10425        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10426            return -1;
10427        }
10428
10429        return timeout;
10430    }
10431
10432    /**
10433     * Handle input dispatching timeouts.
10434     * Returns whether input dispatching should be aborted or not.
10435     */
10436    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10437            final ActivityRecord activity, final ActivityRecord parent,
10438            final boolean aboveSystem, String reason) {
10439        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10440                != PackageManager.PERMISSION_GRANTED) {
10441            throw new SecurityException("Requires permission "
10442                    + android.Manifest.permission.FILTER_EVENTS);
10443        }
10444
10445        final String annotation;
10446        if (reason == null) {
10447            annotation = "Input dispatching timed out";
10448        } else {
10449            annotation = "Input dispatching timed out (" + reason + ")";
10450        }
10451
10452        if (proc != null) {
10453            synchronized (this) {
10454                if (proc.debugging) {
10455                    return false;
10456                }
10457
10458                if (mDidDexOpt) {
10459                    // Give more time since we were dexopting.
10460                    mDidDexOpt = false;
10461                    return false;
10462                }
10463
10464                if (proc.instrumentationClass != null) {
10465                    Bundle info = new Bundle();
10466                    info.putString("shortMsg", "keyDispatchingTimedOut");
10467                    info.putString("longMsg", annotation);
10468                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10469                    return true;
10470                }
10471            }
10472            mHandler.post(new Runnable() {
10473                @Override
10474                public void run() {
10475                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10476                }
10477            });
10478        }
10479
10480        return true;
10481    }
10482
10483    public Bundle getAssistContextExtras(int requestType) {
10484        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10485                UserHandle.getCallingUserId());
10486        if (pae == null) {
10487            return null;
10488        }
10489        synchronized (pae) {
10490            while (!pae.haveResult) {
10491                try {
10492                    pae.wait();
10493                } catch (InterruptedException e) {
10494                }
10495            }
10496            if (pae.result != null) {
10497                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10498            }
10499        }
10500        synchronized (this) {
10501            mPendingAssistExtras.remove(pae);
10502            mHandler.removeCallbacks(pae);
10503        }
10504        return pae.extras;
10505    }
10506
10507    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10508            int userHandle) {
10509        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10510                "getAssistContextExtras()");
10511        PendingAssistExtras pae;
10512        Bundle extras = new Bundle();
10513        synchronized (this) {
10514            ActivityRecord activity = getFocusedStack().mResumedActivity;
10515            if (activity == null) {
10516                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10517                return null;
10518            }
10519            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10520            if (activity.app == null || activity.app.thread == null) {
10521                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10522                return null;
10523            }
10524            if (activity.app.pid == Binder.getCallingPid()) {
10525                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10526                return null;
10527            }
10528            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10529            try {
10530                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10531                        requestType);
10532                mPendingAssistExtras.add(pae);
10533                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10534            } catch (RemoteException e) {
10535                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10536                return null;
10537            }
10538            return pae;
10539        }
10540    }
10541
10542    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10543        PendingAssistExtras pae = (PendingAssistExtras)token;
10544        synchronized (pae) {
10545            pae.result = extras;
10546            pae.haveResult = true;
10547            pae.notifyAll();
10548            if (pae.intent == null) {
10549                // Caller is just waiting for the result.
10550                return;
10551            }
10552        }
10553
10554        // We are now ready to launch the assist activity.
10555        synchronized (this) {
10556            boolean exists = mPendingAssistExtras.remove(pae);
10557            mHandler.removeCallbacks(pae);
10558            if (!exists) {
10559                // Timed out.
10560                return;
10561            }
10562        }
10563        pae.intent.replaceExtras(extras);
10564        if (pae.hint != null) {
10565            pae.intent.putExtra(pae.hint, true);
10566        }
10567        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10568                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10569                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10570        closeSystemDialogs("assist");
10571        try {
10572            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10573        } catch (ActivityNotFoundException e) {
10574            Slog.w(TAG, "No activity to handle assist action.", e);
10575        }
10576    }
10577
10578    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10579        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10580    }
10581
10582    public void registerProcessObserver(IProcessObserver observer) {
10583        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10584                "registerProcessObserver()");
10585        synchronized (this) {
10586            mProcessObservers.register(observer);
10587        }
10588    }
10589
10590    @Override
10591    public void unregisterProcessObserver(IProcessObserver observer) {
10592        synchronized (this) {
10593            mProcessObservers.unregister(observer);
10594        }
10595    }
10596
10597    @Override
10598    public boolean convertFromTranslucent(IBinder token) {
10599        final long origId = Binder.clearCallingIdentity();
10600        try {
10601            synchronized (this) {
10602                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10603                if (r == null) {
10604                    return false;
10605                }
10606                final boolean translucentChanged = r.changeWindowTranslucency(true);
10607                if (translucentChanged) {
10608                    r.task.stack.releaseBackgroundResources();
10609                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10610                }
10611                mWindowManager.setAppFullscreen(token, true);
10612                return translucentChanged;
10613            }
10614        } finally {
10615            Binder.restoreCallingIdentity(origId);
10616        }
10617    }
10618
10619    @Override
10620    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10621        final long origId = Binder.clearCallingIdentity();
10622        try {
10623            synchronized (this) {
10624                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10625                if (r == null) {
10626                    return false;
10627                }
10628                int index = r.task.mActivities.lastIndexOf(r);
10629                if (index > 0) {
10630                    ActivityRecord under = r.task.mActivities.get(index - 1);
10631                    under.returningOptions = options;
10632                }
10633                final boolean translucentChanged = r.changeWindowTranslucency(false);
10634                if (translucentChanged) {
10635                    r.task.stack.convertToTranslucent(r);
10636                }
10637                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10638                mWindowManager.setAppFullscreen(token, false);
10639                return translucentChanged;
10640            }
10641        } finally {
10642            Binder.restoreCallingIdentity(origId);
10643        }
10644    }
10645
10646    @Override
10647    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10648        final long origId = Binder.clearCallingIdentity();
10649        try {
10650            synchronized (this) {
10651                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10652                if (r != null) {
10653                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10654                }
10655            }
10656            return false;
10657        } finally {
10658            Binder.restoreCallingIdentity(origId);
10659        }
10660    }
10661
10662    @Override
10663    public boolean isBackgroundVisibleBehind(IBinder token) {
10664        final long origId = Binder.clearCallingIdentity();
10665        try {
10666            synchronized (this) {
10667                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10668                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10669                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10670                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10671                return visible;
10672            }
10673        } finally {
10674            Binder.restoreCallingIdentity(origId);
10675        }
10676    }
10677
10678    @Override
10679    public ActivityOptions getActivityOptions(IBinder token) {
10680        final long origId = Binder.clearCallingIdentity();
10681        try {
10682            synchronized (this) {
10683                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10684                if (r != null) {
10685                    final ActivityOptions activityOptions = r.pendingOptions;
10686                    r.pendingOptions = null;
10687                    return activityOptions;
10688                }
10689                return null;
10690            }
10691        } finally {
10692            Binder.restoreCallingIdentity(origId);
10693        }
10694    }
10695
10696    @Override
10697    public void setImmersive(IBinder token, boolean immersive) {
10698        synchronized(this) {
10699            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10700            if (r == null) {
10701                throw new IllegalArgumentException();
10702            }
10703            r.immersive = immersive;
10704
10705            // update associated state if we're frontmost
10706            if (r == mFocusedActivity) {
10707                if (DEBUG_IMMERSIVE) {
10708                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10709                }
10710                applyUpdateLockStateLocked(r);
10711            }
10712        }
10713    }
10714
10715    @Override
10716    public boolean isImmersive(IBinder token) {
10717        synchronized (this) {
10718            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10719            if (r == null) {
10720                throw new IllegalArgumentException();
10721            }
10722            return r.immersive;
10723        }
10724    }
10725
10726    public boolean isTopActivityImmersive() {
10727        enforceNotIsolatedCaller("startActivity");
10728        synchronized (this) {
10729            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10730            return (r != null) ? r.immersive : false;
10731        }
10732    }
10733
10734    @Override
10735    public boolean isTopOfTask(IBinder token) {
10736        synchronized (this) {
10737            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10738            if (r == null) {
10739                throw new IllegalArgumentException();
10740            }
10741            return r.task.getTopActivity() == r;
10742        }
10743    }
10744
10745    public final void enterSafeMode() {
10746        synchronized(this) {
10747            // It only makes sense to do this before the system is ready
10748            // and started launching other packages.
10749            if (!mSystemReady) {
10750                try {
10751                    AppGlobals.getPackageManager().enterSafeMode();
10752                } catch (RemoteException e) {
10753                }
10754            }
10755
10756            mSafeMode = true;
10757        }
10758    }
10759
10760    public final void showSafeModeOverlay() {
10761        View v = LayoutInflater.from(mContext).inflate(
10762                com.android.internal.R.layout.safe_mode, null);
10763        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10764        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10765        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10766        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10767        lp.gravity = Gravity.BOTTOM | Gravity.START;
10768        lp.format = v.getBackground().getOpacity();
10769        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10770                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10771        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10772        ((WindowManager)mContext.getSystemService(
10773                Context.WINDOW_SERVICE)).addView(v, lp);
10774    }
10775
10776    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10777        if (!(sender instanceof PendingIntentRecord)) {
10778            return;
10779        }
10780        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10781        synchronized (stats) {
10782            if (mBatteryStatsService.isOnBattery()) {
10783                mBatteryStatsService.enforceCallingPermission();
10784                PendingIntentRecord rec = (PendingIntentRecord)sender;
10785                int MY_UID = Binder.getCallingUid();
10786                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10787                BatteryStatsImpl.Uid.Pkg pkg =
10788                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10789                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10790                pkg.incWakeupsLocked();
10791            }
10792        }
10793    }
10794
10795    public boolean killPids(int[] pids, String pReason, boolean secure) {
10796        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10797            throw new SecurityException("killPids only available to the system");
10798        }
10799        String reason = (pReason == null) ? "Unknown" : pReason;
10800        // XXX Note: don't acquire main activity lock here, because the window
10801        // manager calls in with its locks held.
10802
10803        boolean killed = false;
10804        synchronized (mPidsSelfLocked) {
10805            int[] types = new int[pids.length];
10806            int worstType = 0;
10807            for (int i=0; i<pids.length; i++) {
10808                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10809                if (proc != null) {
10810                    int type = proc.setAdj;
10811                    types[i] = type;
10812                    if (type > worstType) {
10813                        worstType = type;
10814                    }
10815                }
10816            }
10817
10818            // If the worst oom_adj is somewhere in the cached proc LRU range,
10819            // then constrain it so we will kill all cached procs.
10820            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10821                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10822                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10823            }
10824
10825            // If this is not a secure call, don't let it kill processes that
10826            // are important.
10827            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10828                worstType = ProcessList.SERVICE_ADJ;
10829            }
10830
10831            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10832            for (int i=0; i<pids.length; i++) {
10833                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10834                if (proc == null) {
10835                    continue;
10836                }
10837                int adj = proc.setAdj;
10838                if (adj >= worstType && !proc.killedByAm) {
10839                    proc.kill(reason, true);
10840                    killed = true;
10841                }
10842            }
10843        }
10844        return killed;
10845    }
10846
10847    @Override
10848    public void killUid(int uid, String reason) {
10849        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10850            throw new SecurityException("killUid only available to the system");
10851        }
10852        synchronized (this) {
10853            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10854                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10855                    reason != null ? reason : "kill uid");
10856        }
10857    }
10858
10859    @Override
10860    public boolean killProcessesBelowForeground(String reason) {
10861        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10862            throw new SecurityException("killProcessesBelowForeground() only available to system");
10863        }
10864
10865        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10866    }
10867
10868    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10869        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10870            throw new SecurityException("killProcessesBelowAdj() only available to system");
10871        }
10872
10873        boolean killed = false;
10874        synchronized (mPidsSelfLocked) {
10875            final int size = mPidsSelfLocked.size();
10876            for (int i = 0; i < size; i++) {
10877                final int pid = mPidsSelfLocked.keyAt(i);
10878                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10879                if (proc == null) continue;
10880
10881                final int adj = proc.setAdj;
10882                if (adj > belowAdj && !proc.killedByAm) {
10883                    proc.kill(reason, true);
10884                    killed = true;
10885                }
10886            }
10887        }
10888        return killed;
10889    }
10890
10891    @Override
10892    public void hang(final IBinder who, boolean allowRestart) {
10893        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10894                != PackageManager.PERMISSION_GRANTED) {
10895            throw new SecurityException("Requires permission "
10896                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10897        }
10898
10899        final IBinder.DeathRecipient death = new DeathRecipient() {
10900            @Override
10901            public void binderDied() {
10902                synchronized (this) {
10903                    notifyAll();
10904                }
10905            }
10906        };
10907
10908        try {
10909            who.linkToDeath(death, 0);
10910        } catch (RemoteException e) {
10911            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10912            return;
10913        }
10914
10915        synchronized (this) {
10916            Watchdog.getInstance().setAllowRestart(allowRestart);
10917            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10918            synchronized (death) {
10919                while (who.isBinderAlive()) {
10920                    try {
10921                        death.wait();
10922                    } catch (InterruptedException e) {
10923                    }
10924                }
10925            }
10926            Watchdog.getInstance().setAllowRestart(true);
10927        }
10928    }
10929
10930    @Override
10931    public void restart() {
10932        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10933                != PackageManager.PERMISSION_GRANTED) {
10934            throw new SecurityException("Requires permission "
10935                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10936        }
10937
10938        Log.i(TAG, "Sending shutdown broadcast...");
10939
10940        BroadcastReceiver br = new BroadcastReceiver() {
10941            @Override public void onReceive(Context context, Intent intent) {
10942                // Now the broadcast is done, finish up the low-level shutdown.
10943                Log.i(TAG, "Shutting down activity manager...");
10944                shutdown(10000);
10945                Log.i(TAG, "Shutdown complete, restarting!");
10946                Process.killProcess(Process.myPid());
10947                System.exit(10);
10948            }
10949        };
10950
10951        // First send the high-level shut down broadcast.
10952        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10953        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10954        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10955        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10956        mContext.sendOrderedBroadcastAsUser(intent,
10957                UserHandle.ALL, null, br, mHandler, 0, null, null);
10958        */
10959        br.onReceive(mContext, intent);
10960    }
10961
10962    private long getLowRamTimeSinceIdle(long now) {
10963        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10964    }
10965
10966    @Override
10967    public void performIdleMaintenance() {
10968        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10969                != PackageManager.PERMISSION_GRANTED) {
10970            throw new SecurityException("Requires permission "
10971                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10972        }
10973
10974        synchronized (this) {
10975            final long now = SystemClock.uptimeMillis();
10976            final long timeSinceLastIdle = now - mLastIdleTime;
10977            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10978            mLastIdleTime = now;
10979            mLowRamTimeSinceLastIdle = 0;
10980            if (mLowRamStartTime != 0) {
10981                mLowRamStartTime = now;
10982            }
10983
10984            StringBuilder sb = new StringBuilder(128);
10985            sb.append("Idle maintenance over ");
10986            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10987            sb.append(" low RAM for ");
10988            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10989            Slog.i(TAG, sb.toString());
10990
10991            // If at least 1/3 of our time since the last idle period has been spent
10992            // with RAM low, then we want to kill processes.
10993            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10994
10995            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10996                ProcessRecord proc = mLruProcesses.get(i);
10997                if (proc.notCachedSinceIdle) {
10998                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10999                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11000                        if (doKilling && proc.initialIdlePss != 0
11001                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11002                            proc.kill("idle maint (pss " + proc.lastPss
11003                                    + " from " + proc.initialIdlePss + ")", true);
11004                        }
11005                    }
11006                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11007                    proc.notCachedSinceIdle = true;
11008                    proc.initialIdlePss = 0;
11009                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11010                            isSleeping(), now);
11011                }
11012            }
11013
11014            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11015            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11016        }
11017    }
11018
11019    private void retrieveSettings() {
11020        final ContentResolver resolver = mContext.getContentResolver();
11021        String debugApp = Settings.Global.getString(
11022            resolver, Settings.Global.DEBUG_APP);
11023        boolean waitForDebugger = Settings.Global.getInt(
11024            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11025        boolean alwaysFinishActivities = Settings.Global.getInt(
11026            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11027        boolean forceRtl = Settings.Global.getInt(
11028                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11029        // Transfer any global setting for forcing RTL layout, into a System Property
11030        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11031
11032        Configuration configuration = new Configuration();
11033        Settings.System.getConfiguration(resolver, configuration);
11034        if (forceRtl) {
11035            // This will take care of setting the correct layout direction flags
11036            configuration.setLayoutDirection(configuration.locale);
11037        }
11038
11039        synchronized (this) {
11040            mDebugApp = mOrigDebugApp = debugApp;
11041            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11042            mAlwaysFinishActivities = alwaysFinishActivities;
11043            // This happens before any activities are started, so we can
11044            // change mConfiguration in-place.
11045            updateConfigurationLocked(configuration, null, false, true);
11046            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11047        }
11048    }
11049
11050    /** Loads resources after the current configuration has been set. */
11051    private void loadResourcesOnSystemReady() {
11052        final Resources res = mContext.getResources();
11053        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11054        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11055        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11056    }
11057
11058    public boolean testIsSystemReady() {
11059        // no need to synchronize(this) just to read & return the value
11060        return mSystemReady;
11061    }
11062
11063    private static File getCalledPreBootReceiversFile() {
11064        File dataDir = Environment.getDataDirectory();
11065        File systemDir = new File(dataDir, "system");
11066        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11067        return fname;
11068    }
11069
11070    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11071        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11072        File file = getCalledPreBootReceiversFile();
11073        FileInputStream fis = null;
11074        try {
11075            fis = new FileInputStream(file);
11076            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11077            int fvers = dis.readInt();
11078            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11079                String vers = dis.readUTF();
11080                String codename = dis.readUTF();
11081                String build = dis.readUTF();
11082                if (android.os.Build.VERSION.RELEASE.equals(vers)
11083                        && android.os.Build.VERSION.CODENAME.equals(codename)
11084                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11085                    int num = dis.readInt();
11086                    while (num > 0) {
11087                        num--;
11088                        String pkg = dis.readUTF();
11089                        String cls = dis.readUTF();
11090                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11091                    }
11092                }
11093            }
11094        } catch (FileNotFoundException e) {
11095        } catch (IOException e) {
11096            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11097        } finally {
11098            if (fis != null) {
11099                try {
11100                    fis.close();
11101                } catch (IOException e) {
11102                }
11103            }
11104        }
11105        return lastDoneReceivers;
11106    }
11107
11108    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11109        File file = getCalledPreBootReceiversFile();
11110        FileOutputStream fos = null;
11111        DataOutputStream dos = null;
11112        try {
11113            fos = new FileOutputStream(file);
11114            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11115            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11116            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11117            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11118            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11119            dos.writeInt(list.size());
11120            for (int i=0; i<list.size(); i++) {
11121                dos.writeUTF(list.get(i).getPackageName());
11122                dos.writeUTF(list.get(i).getClassName());
11123            }
11124        } catch (IOException e) {
11125            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11126            file.delete();
11127        } finally {
11128            FileUtils.sync(fos);
11129            if (dos != null) {
11130                try {
11131                    dos.close();
11132                } catch (IOException e) {
11133                    // TODO Auto-generated catch block
11134                    e.printStackTrace();
11135                }
11136            }
11137        }
11138    }
11139
11140    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11141            ArrayList<ComponentName> doneReceivers, int userId) {
11142        boolean waitingUpdate = false;
11143        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11144        List<ResolveInfo> ris = null;
11145        try {
11146            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11147                    intent, null, 0, userId);
11148        } catch (RemoteException e) {
11149        }
11150        if (ris != null) {
11151            for (int i=ris.size()-1; i>=0; i--) {
11152                if ((ris.get(i).activityInfo.applicationInfo.flags
11153                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11154                    ris.remove(i);
11155                }
11156            }
11157            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11158
11159            // For User 0, load the version number. When delivering to a new user, deliver
11160            // to all receivers.
11161            if (userId == UserHandle.USER_OWNER) {
11162                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11163                for (int i=0; i<ris.size(); i++) {
11164                    ActivityInfo ai = ris.get(i).activityInfo;
11165                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11166                    if (lastDoneReceivers.contains(comp)) {
11167                        // We already did the pre boot receiver for this app with the current
11168                        // platform version, so don't do it again...
11169                        ris.remove(i);
11170                        i--;
11171                        // ...however, do keep it as one that has been done, so we don't
11172                        // forget about it when rewriting the file of last done receivers.
11173                        doneReceivers.add(comp);
11174                    }
11175                }
11176            }
11177
11178            // If primary user, send broadcast to all available users, else just to userId
11179            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11180                    : new int[] { userId };
11181            for (int i = 0; i < ris.size(); i++) {
11182                ActivityInfo ai = ris.get(i).activityInfo;
11183                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11184                doneReceivers.add(comp);
11185                intent.setComponent(comp);
11186                for (int j=0; j<users.length; j++) {
11187                    IIntentReceiver finisher = null;
11188                    // On last receiver and user, set up a completion callback
11189                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11190                        finisher = new IIntentReceiver.Stub() {
11191                            public void performReceive(Intent intent, int resultCode,
11192                                    String data, Bundle extras, boolean ordered,
11193                                    boolean sticky, int sendingUser) {
11194                                // The raw IIntentReceiver interface is called
11195                                // with the AM lock held, so redispatch to
11196                                // execute our code without the lock.
11197                                mHandler.post(onFinishCallback);
11198                            }
11199                        };
11200                    }
11201                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11202                            + " for user " + users[j]);
11203                    broadcastIntentLocked(null, null, intent, null, finisher,
11204                            0, null, null, null, AppOpsManager.OP_NONE,
11205                            true, false, MY_PID, Process.SYSTEM_UID,
11206                            users[j]);
11207                    if (finisher != null) {
11208                        waitingUpdate = true;
11209                    }
11210                }
11211            }
11212        }
11213
11214        return waitingUpdate;
11215    }
11216
11217    public void systemReady(final Runnable goingCallback) {
11218        synchronized(this) {
11219            if (mSystemReady) {
11220                // If we're done calling all the receivers, run the next "boot phase" passed in
11221                // by the SystemServer
11222                if (goingCallback != null) {
11223                    goingCallback.run();
11224                }
11225                return;
11226            }
11227
11228            // Make sure we have the current profile info, since it is needed for
11229            // security checks.
11230            updateCurrentProfileIdsLocked();
11231
11232            if (mRecentTasks == null) {
11233                mRecentTasks = mTaskPersister.restoreTasksLocked();
11234                if (!mRecentTasks.isEmpty()) {
11235                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11236                }
11237                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11238                mTaskPersister.startPersisting();
11239            }
11240
11241            // Check to see if there are any update receivers to run.
11242            if (!mDidUpdate) {
11243                if (mWaitingUpdate) {
11244                    return;
11245                }
11246                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11247                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11248                    public void run() {
11249                        synchronized (ActivityManagerService.this) {
11250                            mDidUpdate = true;
11251                        }
11252                        writeLastDonePreBootReceivers(doneReceivers);
11253                        showBootMessage(mContext.getText(
11254                                R.string.android_upgrading_complete),
11255                                false);
11256                        systemReady(goingCallback);
11257                    }
11258                }, doneReceivers, UserHandle.USER_OWNER);
11259
11260                if (mWaitingUpdate) {
11261                    return;
11262                }
11263                mDidUpdate = true;
11264            }
11265
11266            mAppOpsService.systemReady();
11267            mSystemReady = true;
11268        }
11269
11270        ArrayList<ProcessRecord> procsToKill = null;
11271        synchronized(mPidsSelfLocked) {
11272            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11273                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11274                if (!isAllowedWhileBooting(proc.info)){
11275                    if (procsToKill == null) {
11276                        procsToKill = new ArrayList<ProcessRecord>();
11277                    }
11278                    procsToKill.add(proc);
11279                }
11280            }
11281        }
11282
11283        synchronized(this) {
11284            if (procsToKill != null) {
11285                for (int i=procsToKill.size()-1; i>=0; i--) {
11286                    ProcessRecord proc = procsToKill.get(i);
11287                    Slog.i(TAG, "Removing system update proc: " + proc);
11288                    removeProcessLocked(proc, true, false, "system update done");
11289                }
11290            }
11291
11292            // Now that we have cleaned up any update processes, we
11293            // are ready to start launching real processes and know that
11294            // we won't trample on them any more.
11295            mProcessesReady = true;
11296        }
11297
11298        Slog.i(TAG, "System now ready");
11299        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11300            SystemClock.uptimeMillis());
11301
11302        synchronized(this) {
11303            // Make sure we have no pre-ready processes sitting around.
11304
11305            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11306                ResolveInfo ri = mContext.getPackageManager()
11307                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11308                                STOCK_PM_FLAGS);
11309                CharSequence errorMsg = null;
11310                if (ri != null) {
11311                    ActivityInfo ai = ri.activityInfo;
11312                    ApplicationInfo app = ai.applicationInfo;
11313                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11314                        mTopAction = Intent.ACTION_FACTORY_TEST;
11315                        mTopData = null;
11316                        mTopComponent = new ComponentName(app.packageName,
11317                                ai.name);
11318                    } else {
11319                        errorMsg = mContext.getResources().getText(
11320                                com.android.internal.R.string.factorytest_not_system);
11321                    }
11322                } else {
11323                    errorMsg = mContext.getResources().getText(
11324                            com.android.internal.R.string.factorytest_no_action);
11325                }
11326                if (errorMsg != null) {
11327                    mTopAction = null;
11328                    mTopData = null;
11329                    mTopComponent = null;
11330                    Message msg = Message.obtain();
11331                    msg.what = SHOW_FACTORY_ERROR_MSG;
11332                    msg.getData().putCharSequence("msg", errorMsg);
11333                    mHandler.sendMessage(msg);
11334                }
11335            }
11336        }
11337
11338        retrieveSettings();
11339        loadResourcesOnSystemReady();
11340
11341        synchronized (this) {
11342            readGrantedUriPermissionsLocked();
11343        }
11344
11345        if (goingCallback != null) goingCallback.run();
11346
11347        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11348                Integer.toString(mCurrentUserId), mCurrentUserId);
11349        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11350                Integer.toString(mCurrentUserId), mCurrentUserId);
11351        mSystemServiceManager.startUser(mCurrentUserId);
11352
11353        synchronized (this) {
11354            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11355                try {
11356                    List apps = AppGlobals.getPackageManager().
11357                        getPersistentApplications(STOCK_PM_FLAGS);
11358                    if (apps != null) {
11359                        int N = apps.size();
11360                        int i;
11361                        for (i=0; i<N; i++) {
11362                            ApplicationInfo info
11363                                = (ApplicationInfo)apps.get(i);
11364                            if (info != null &&
11365                                    !info.packageName.equals("android")) {
11366                                addAppLocked(info, false, null /* ABI override */);
11367                            }
11368                        }
11369                    }
11370                } catch (RemoteException ex) {
11371                    // pm is in same process, this will never happen.
11372                }
11373            }
11374
11375            // Start up initial activity.
11376            mBooting = true;
11377            startHomeActivityLocked(mCurrentUserId);
11378
11379            try {
11380                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11381                    Message msg = Message.obtain();
11382                    msg.what = SHOW_UID_ERROR_MSG;
11383                    mHandler.sendMessage(msg);
11384                }
11385            } catch (RemoteException e) {
11386            }
11387
11388            long ident = Binder.clearCallingIdentity();
11389            try {
11390                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11391                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11392                        | Intent.FLAG_RECEIVER_FOREGROUND);
11393                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11394                broadcastIntentLocked(null, null, intent,
11395                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11396                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11397                intent = new Intent(Intent.ACTION_USER_STARTING);
11398                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11399                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11400                broadcastIntentLocked(null, null, intent,
11401                        null, new IIntentReceiver.Stub() {
11402                            @Override
11403                            public void performReceive(Intent intent, int resultCode, String data,
11404                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11405                                    throws RemoteException {
11406                            }
11407                        }, 0, null, null,
11408                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11409                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11410            } catch (Throwable t) {
11411                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11412            } finally {
11413                Binder.restoreCallingIdentity(ident);
11414            }
11415            mStackSupervisor.resumeTopActivitiesLocked();
11416            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11417        }
11418    }
11419
11420    private boolean makeAppCrashingLocked(ProcessRecord app,
11421            String shortMsg, String longMsg, String stackTrace) {
11422        app.crashing = true;
11423        app.crashingReport = generateProcessError(app,
11424                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11425        startAppProblemLocked(app);
11426        app.stopFreezingAllLocked();
11427        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11428    }
11429
11430    private void makeAppNotRespondingLocked(ProcessRecord app,
11431            String activity, String shortMsg, String longMsg) {
11432        app.notResponding = true;
11433        app.notRespondingReport = generateProcessError(app,
11434                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11435                activity, shortMsg, longMsg, null);
11436        startAppProblemLocked(app);
11437        app.stopFreezingAllLocked();
11438    }
11439
11440    /**
11441     * Generate a process error record, suitable for attachment to a ProcessRecord.
11442     *
11443     * @param app The ProcessRecord in which the error occurred.
11444     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11445     *                      ActivityManager.AppErrorStateInfo
11446     * @param activity The activity associated with the crash, if known.
11447     * @param shortMsg Short message describing the crash.
11448     * @param longMsg Long message describing the crash.
11449     * @param stackTrace Full crash stack trace, may be null.
11450     *
11451     * @return Returns a fully-formed AppErrorStateInfo record.
11452     */
11453    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11454            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11455        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11456
11457        report.condition = condition;
11458        report.processName = app.processName;
11459        report.pid = app.pid;
11460        report.uid = app.info.uid;
11461        report.tag = activity;
11462        report.shortMsg = shortMsg;
11463        report.longMsg = longMsg;
11464        report.stackTrace = stackTrace;
11465
11466        return report;
11467    }
11468
11469    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11470        synchronized (this) {
11471            app.crashing = false;
11472            app.crashingReport = null;
11473            app.notResponding = false;
11474            app.notRespondingReport = null;
11475            if (app.anrDialog == fromDialog) {
11476                app.anrDialog = null;
11477            }
11478            if (app.waitDialog == fromDialog) {
11479                app.waitDialog = null;
11480            }
11481            if (app.pid > 0 && app.pid != MY_PID) {
11482                handleAppCrashLocked(app, null, null, null);
11483                app.kill("user request after error", true);
11484            }
11485        }
11486    }
11487
11488    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11489            String stackTrace) {
11490        long now = SystemClock.uptimeMillis();
11491
11492        Long crashTime;
11493        if (!app.isolated) {
11494            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11495        } else {
11496            crashTime = null;
11497        }
11498        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11499            // This process loses!
11500            Slog.w(TAG, "Process " + app.info.processName
11501                    + " has crashed too many times: killing!");
11502            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11503                    app.userId, app.info.processName, app.uid);
11504            mStackSupervisor.handleAppCrashLocked(app);
11505            if (!app.persistent) {
11506                // We don't want to start this process again until the user
11507                // explicitly does so...  but for persistent process, we really
11508                // need to keep it running.  If a persistent process is actually
11509                // repeatedly crashing, then badness for everyone.
11510                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11511                        app.info.processName);
11512                if (!app.isolated) {
11513                    // XXX We don't have a way to mark isolated processes
11514                    // as bad, since they don't have a peristent identity.
11515                    mBadProcesses.put(app.info.processName, app.uid,
11516                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11517                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11518                }
11519                app.bad = true;
11520                app.removed = true;
11521                // Don't let services in this process be restarted and potentially
11522                // annoy the user repeatedly.  Unless it is persistent, since those
11523                // processes run critical code.
11524                removeProcessLocked(app, false, false, "crash");
11525                mStackSupervisor.resumeTopActivitiesLocked();
11526                return false;
11527            }
11528            mStackSupervisor.resumeTopActivitiesLocked();
11529        } else {
11530            mStackSupervisor.finishTopRunningActivityLocked(app);
11531        }
11532
11533        // Bump up the crash count of any services currently running in the proc.
11534        for (int i=app.services.size()-1; i>=0; i--) {
11535            // Any services running in the application need to be placed
11536            // back in the pending list.
11537            ServiceRecord sr = app.services.valueAt(i);
11538            sr.crashCount++;
11539        }
11540
11541        // If the crashing process is what we consider to be the "home process" and it has been
11542        // replaced by a third-party app, clear the package preferred activities from packages
11543        // with a home activity running in the process to prevent a repeatedly crashing app
11544        // from blocking the user to manually clear the list.
11545        final ArrayList<ActivityRecord> activities = app.activities;
11546        if (app == mHomeProcess && activities.size() > 0
11547                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11548            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11549                final ActivityRecord r = activities.get(activityNdx);
11550                if (r.isHomeActivity()) {
11551                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11552                    try {
11553                        ActivityThread.getPackageManager()
11554                                .clearPackagePreferredActivities(r.packageName);
11555                    } catch (RemoteException c) {
11556                        // pm is in same process, this will never happen.
11557                    }
11558                }
11559            }
11560        }
11561
11562        if (!app.isolated) {
11563            // XXX Can't keep track of crash times for isolated processes,
11564            // because they don't have a perisistent identity.
11565            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11566        }
11567
11568        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11569        return true;
11570    }
11571
11572    void startAppProblemLocked(ProcessRecord app) {
11573        // If this app is not running under the current user, then we
11574        // can't give it a report button because that would require
11575        // launching the report UI under a different user.
11576        app.errorReportReceiver = null;
11577
11578        for (int userId : mCurrentProfileIds) {
11579            if (app.userId == userId) {
11580                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11581                        mContext, app.info.packageName, app.info.flags);
11582            }
11583        }
11584        skipCurrentReceiverLocked(app);
11585    }
11586
11587    void skipCurrentReceiverLocked(ProcessRecord app) {
11588        for (BroadcastQueue queue : mBroadcastQueues) {
11589            queue.skipCurrentReceiverLocked(app);
11590        }
11591    }
11592
11593    /**
11594     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11595     * The application process will exit immediately after this call returns.
11596     * @param app object of the crashing app, null for the system server
11597     * @param crashInfo describing the exception
11598     */
11599    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11600        ProcessRecord r = findAppProcess(app, "Crash");
11601        final String processName = app == null ? "system_server"
11602                : (r == null ? "unknown" : r.processName);
11603
11604        handleApplicationCrashInner("crash", r, processName, crashInfo);
11605    }
11606
11607    /* Native crash reporting uses this inner version because it needs to be somewhat
11608     * decoupled from the AM-managed cleanup lifecycle
11609     */
11610    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11611            ApplicationErrorReport.CrashInfo crashInfo) {
11612        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11613                UserHandle.getUserId(Binder.getCallingUid()), processName,
11614                r == null ? -1 : r.info.flags,
11615                crashInfo.exceptionClassName,
11616                crashInfo.exceptionMessage,
11617                crashInfo.throwFileName,
11618                crashInfo.throwLineNumber);
11619
11620        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11621
11622        crashApplication(r, crashInfo);
11623    }
11624
11625    public void handleApplicationStrictModeViolation(
11626            IBinder app,
11627            int violationMask,
11628            StrictMode.ViolationInfo info) {
11629        ProcessRecord r = findAppProcess(app, "StrictMode");
11630        if (r == null) {
11631            return;
11632        }
11633
11634        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11635            Integer stackFingerprint = info.hashCode();
11636            boolean logIt = true;
11637            synchronized (mAlreadyLoggedViolatedStacks) {
11638                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11639                    logIt = false;
11640                    // TODO: sub-sample into EventLog for these, with
11641                    // the info.durationMillis?  Then we'd get
11642                    // the relative pain numbers, without logging all
11643                    // the stack traces repeatedly.  We'd want to do
11644                    // likewise in the client code, which also does
11645                    // dup suppression, before the Binder call.
11646                } else {
11647                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11648                        mAlreadyLoggedViolatedStacks.clear();
11649                    }
11650                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11651                }
11652            }
11653            if (logIt) {
11654                logStrictModeViolationToDropBox(r, info);
11655            }
11656        }
11657
11658        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11659            AppErrorResult result = new AppErrorResult();
11660            synchronized (this) {
11661                final long origId = Binder.clearCallingIdentity();
11662
11663                Message msg = Message.obtain();
11664                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11665                HashMap<String, Object> data = new HashMap<String, Object>();
11666                data.put("result", result);
11667                data.put("app", r);
11668                data.put("violationMask", violationMask);
11669                data.put("info", info);
11670                msg.obj = data;
11671                mHandler.sendMessage(msg);
11672
11673                Binder.restoreCallingIdentity(origId);
11674            }
11675            int res = result.get();
11676            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11677        }
11678    }
11679
11680    // Depending on the policy in effect, there could be a bunch of
11681    // these in quick succession so we try to batch these together to
11682    // minimize disk writes, number of dropbox entries, and maximize
11683    // compression, by having more fewer, larger records.
11684    private void logStrictModeViolationToDropBox(
11685            ProcessRecord process,
11686            StrictMode.ViolationInfo info) {
11687        if (info == null) {
11688            return;
11689        }
11690        final boolean isSystemApp = process == null ||
11691                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11692                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11693        final String processName = process == null ? "unknown" : process.processName;
11694        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11695        final DropBoxManager dbox = (DropBoxManager)
11696                mContext.getSystemService(Context.DROPBOX_SERVICE);
11697
11698        // Exit early if the dropbox isn't configured to accept this report type.
11699        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11700
11701        boolean bufferWasEmpty;
11702        boolean needsFlush;
11703        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11704        synchronized (sb) {
11705            bufferWasEmpty = sb.length() == 0;
11706            appendDropBoxProcessHeaders(process, processName, sb);
11707            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11708            sb.append("System-App: ").append(isSystemApp).append("\n");
11709            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11710            if (info.violationNumThisLoop != 0) {
11711                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11712            }
11713            if (info.numAnimationsRunning != 0) {
11714                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11715            }
11716            if (info.broadcastIntentAction != null) {
11717                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11718            }
11719            if (info.durationMillis != -1) {
11720                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11721            }
11722            if (info.numInstances != -1) {
11723                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11724            }
11725            if (info.tags != null) {
11726                for (String tag : info.tags) {
11727                    sb.append("Span-Tag: ").append(tag).append("\n");
11728                }
11729            }
11730            sb.append("\n");
11731            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11732                sb.append(info.crashInfo.stackTrace);
11733            }
11734            sb.append("\n");
11735
11736            // Only buffer up to ~64k.  Various logging bits truncate
11737            // things at 128k.
11738            needsFlush = (sb.length() > 64 * 1024);
11739        }
11740
11741        // Flush immediately if the buffer's grown too large, or this
11742        // is a non-system app.  Non-system apps are isolated with a
11743        // different tag & policy and not batched.
11744        //
11745        // Batching is useful during internal testing with
11746        // StrictMode settings turned up high.  Without batching,
11747        // thousands of separate files could be created on boot.
11748        if (!isSystemApp || needsFlush) {
11749            new Thread("Error dump: " + dropboxTag) {
11750                @Override
11751                public void run() {
11752                    String report;
11753                    synchronized (sb) {
11754                        report = sb.toString();
11755                        sb.delete(0, sb.length());
11756                        sb.trimToSize();
11757                    }
11758                    if (report.length() != 0) {
11759                        dbox.addText(dropboxTag, report);
11760                    }
11761                }
11762            }.start();
11763            return;
11764        }
11765
11766        // System app batching:
11767        if (!bufferWasEmpty) {
11768            // An existing dropbox-writing thread is outstanding, so
11769            // we don't need to start it up.  The existing thread will
11770            // catch the buffer appends we just did.
11771            return;
11772        }
11773
11774        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11775        // (After this point, we shouldn't access AMS internal data structures.)
11776        new Thread("Error dump: " + dropboxTag) {
11777            @Override
11778            public void run() {
11779                // 5 second sleep to let stacks arrive and be batched together
11780                try {
11781                    Thread.sleep(5000);  // 5 seconds
11782                } catch (InterruptedException e) {}
11783
11784                String errorReport;
11785                synchronized (mStrictModeBuffer) {
11786                    errorReport = mStrictModeBuffer.toString();
11787                    if (errorReport.length() == 0) {
11788                        return;
11789                    }
11790                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11791                    mStrictModeBuffer.trimToSize();
11792                }
11793                dbox.addText(dropboxTag, errorReport);
11794            }
11795        }.start();
11796    }
11797
11798    /**
11799     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11800     * @param app object of the crashing app, null for the system server
11801     * @param tag reported by the caller
11802     * @param system whether this wtf is coming from the system
11803     * @param crashInfo describing the context of the error
11804     * @return true if the process should exit immediately (WTF is fatal)
11805     */
11806    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11807            final ApplicationErrorReport.CrashInfo crashInfo) {
11808        final int callingUid = Binder.getCallingUid();
11809        final int callingPid = Binder.getCallingPid();
11810
11811        if (system) {
11812            // If this is coming from the system, we could very well have low-level
11813            // system locks held, so we want to do this all asynchronously.  And we
11814            // never want this to become fatal, so there is that too.
11815            mHandler.post(new Runnable() {
11816                @Override public void run() {
11817                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11818                }
11819            });
11820            return false;
11821        }
11822
11823        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11824                crashInfo);
11825
11826        if (r != null && r.pid != Process.myPid() &&
11827                Settings.Global.getInt(mContext.getContentResolver(),
11828                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11829            crashApplication(r, crashInfo);
11830            return true;
11831        } else {
11832            return false;
11833        }
11834    }
11835
11836    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11837            final ApplicationErrorReport.CrashInfo crashInfo) {
11838        final ProcessRecord r = findAppProcess(app, "WTF");
11839        final String processName = app == null ? "system_server"
11840                : (r == null ? "unknown" : r.processName);
11841
11842        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11843                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11844
11845        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11846
11847        return r;
11848    }
11849
11850    /**
11851     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11852     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11853     */
11854    private ProcessRecord findAppProcess(IBinder app, String reason) {
11855        if (app == null) {
11856            return null;
11857        }
11858
11859        synchronized (this) {
11860            final int NP = mProcessNames.getMap().size();
11861            for (int ip=0; ip<NP; ip++) {
11862                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11863                final int NA = apps.size();
11864                for (int ia=0; ia<NA; ia++) {
11865                    ProcessRecord p = apps.valueAt(ia);
11866                    if (p.thread != null && p.thread.asBinder() == app) {
11867                        return p;
11868                    }
11869                }
11870            }
11871
11872            Slog.w(TAG, "Can't find mystery application for " + reason
11873                    + " from pid=" + Binder.getCallingPid()
11874                    + " uid=" + Binder.getCallingUid() + ": " + app);
11875            return null;
11876        }
11877    }
11878
11879    /**
11880     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11881     * to append various headers to the dropbox log text.
11882     */
11883    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11884            StringBuilder sb) {
11885        // Watchdog thread ends up invoking this function (with
11886        // a null ProcessRecord) to add the stack file to dropbox.
11887        // Do not acquire a lock on this (am) in such cases, as it
11888        // could cause a potential deadlock, if and when watchdog
11889        // is invoked due to unavailability of lock on am and it
11890        // would prevent watchdog from killing system_server.
11891        if (process == null) {
11892            sb.append("Process: ").append(processName).append("\n");
11893            return;
11894        }
11895        // Note: ProcessRecord 'process' is guarded by the service
11896        // instance.  (notably process.pkgList, which could otherwise change
11897        // concurrently during execution of this method)
11898        synchronized (this) {
11899            sb.append("Process: ").append(processName).append("\n");
11900            int flags = process.info.flags;
11901            IPackageManager pm = AppGlobals.getPackageManager();
11902            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11903            for (int ip=0; ip<process.pkgList.size(); ip++) {
11904                String pkg = process.pkgList.keyAt(ip);
11905                sb.append("Package: ").append(pkg);
11906                try {
11907                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11908                    if (pi != null) {
11909                        sb.append(" v").append(pi.versionCode);
11910                        if (pi.versionName != null) {
11911                            sb.append(" (").append(pi.versionName).append(")");
11912                        }
11913                    }
11914                } catch (RemoteException e) {
11915                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11916                }
11917                sb.append("\n");
11918            }
11919        }
11920    }
11921
11922    private static String processClass(ProcessRecord process) {
11923        if (process == null || process.pid == MY_PID) {
11924            return "system_server";
11925        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11926            return "system_app";
11927        } else {
11928            return "data_app";
11929        }
11930    }
11931
11932    /**
11933     * Write a description of an error (crash, WTF, ANR) to the drop box.
11934     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11935     * @param process which caused the error, null means the system server
11936     * @param activity which triggered the error, null if unknown
11937     * @param parent activity related to the error, null if unknown
11938     * @param subject line related to the error, null if absent
11939     * @param report in long form describing the error, null if absent
11940     * @param logFile to include in the report, null if none
11941     * @param crashInfo giving an application stack trace, null if absent
11942     */
11943    public void addErrorToDropBox(String eventType,
11944            ProcessRecord process, String processName, ActivityRecord activity,
11945            ActivityRecord parent, String subject,
11946            final String report, final File logFile,
11947            final ApplicationErrorReport.CrashInfo crashInfo) {
11948        // NOTE -- this must never acquire the ActivityManagerService lock,
11949        // otherwise the watchdog may be prevented from resetting the system.
11950
11951        final String dropboxTag = processClass(process) + "_" + eventType;
11952        final DropBoxManager dbox = (DropBoxManager)
11953                mContext.getSystemService(Context.DROPBOX_SERVICE);
11954
11955        // Exit early if the dropbox isn't configured to accept this report type.
11956        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11957
11958        final StringBuilder sb = new StringBuilder(1024);
11959        appendDropBoxProcessHeaders(process, processName, sb);
11960        if (activity != null) {
11961            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11962        }
11963        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11964            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11965        }
11966        if (parent != null && parent != activity) {
11967            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11968        }
11969        if (subject != null) {
11970            sb.append("Subject: ").append(subject).append("\n");
11971        }
11972        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11973        if (Debug.isDebuggerConnected()) {
11974            sb.append("Debugger: Connected\n");
11975        }
11976        sb.append("\n");
11977
11978        // Do the rest in a worker thread to avoid blocking the caller on I/O
11979        // (After this point, we shouldn't access AMS internal data structures.)
11980        Thread worker = new Thread("Error dump: " + dropboxTag) {
11981            @Override
11982            public void run() {
11983                if (report != null) {
11984                    sb.append(report);
11985                }
11986                if (logFile != null) {
11987                    try {
11988                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11989                                    "\n\n[[TRUNCATED]]"));
11990                    } catch (IOException e) {
11991                        Slog.e(TAG, "Error reading " + logFile, e);
11992                    }
11993                }
11994                if (crashInfo != null && crashInfo.stackTrace != null) {
11995                    sb.append(crashInfo.stackTrace);
11996                }
11997
11998                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11999                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12000                if (lines > 0) {
12001                    sb.append("\n");
12002
12003                    // Merge several logcat streams, and take the last N lines
12004                    InputStreamReader input = null;
12005                    try {
12006                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12007                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12008                                "-b", "crash",
12009                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12010
12011                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12012                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12013                        input = new InputStreamReader(logcat.getInputStream());
12014
12015                        int num;
12016                        char[] buf = new char[8192];
12017                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12018                    } catch (IOException e) {
12019                        Slog.e(TAG, "Error running logcat", e);
12020                    } finally {
12021                        if (input != null) try { input.close(); } catch (IOException e) {}
12022                    }
12023                }
12024
12025                dbox.addText(dropboxTag, sb.toString());
12026            }
12027        };
12028
12029        if (process == null) {
12030            // If process is null, we are being called from some internal code
12031            // and may be about to die -- run this synchronously.
12032            worker.run();
12033        } else {
12034            worker.start();
12035        }
12036    }
12037
12038    /**
12039     * Bring up the "unexpected error" dialog box for a crashing app.
12040     * Deal with edge cases (intercepts from instrumented applications,
12041     * ActivityController, error intent receivers, that sort of thing).
12042     * @param r the application crashing
12043     * @param crashInfo describing the failure
12044     */
12045    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12046        long timeMillis = System.currentTimeMillis();
12047        String shortMsg = crashInfo.exceptionClassName;
12048        String longMsg = crashInfo.exceptionMessage;
12049        String stackTrace = crashInfo.stackTrace;
12050        if (shortMsg != null && longMsg != null) {
12051            longMsg = shortMsg + ": " + longMsg;
12052        } else if (shortMsg != null) {
12053            longMsg = shortMsg;
12054        }
12055
12056        AppErrorResult result = new AppErrorResult();
12057        synchronized (this) {
12058            if (mController != null) {
12059                try {
12060                    String name = r != null ? r.processName : null;
12061                    int pid = r != null ? r.pid : Binder.getCallingPid();
12062                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12063                    if (!mController.appCrashed(name, pid,
12064                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12065                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12066                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12067                            Slog.w(TAG, "Skip killing native crashed app " + name
12068                                    + "(" + pid + ") during testing");
12069                        } else {
12070                            Slog.w(TAG, "Force-killing crashed app " + name
12071                                    + " at watcher's request");
12072                            if (r != null) {
12073                                r.kill("crash", true);
12074                            } else {
12075                                // Huh.
12076                                Process.killProcess(pid);
12077                                Process.killProcessGroup(uid, pid);
12078                            }
12079                        }
12080                        return;
12081                    }
12082                } catch (RemoteException e) {
12083                    mController = null;
12084                    Watchdog.getInstance().setActivityController(null);
12085                }
12086            }
12087
12088            final long origId = Binder.clearCallingIdentity();
12089
12090            // If this process is running instrumentation, finish it.
12091            if (r != null && r.instrumentationClass != null) {
12092                Slog.w(TAG, "Error in app " + r.processName
12093                      + " running instrumentation " + r.instrumentationClass + ":");
12094                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12095                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12096                Bundle info = new Bundle();
12097                info.putString("shortMsg", shortMsg);
12098                info.putString("longMsg", longMsg);
12099                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12100                Binder.restoreCallingIdentity(origId);
12101                return;
12102            }
12103
12104            // If we can't identify the process or it's already exceeded its crash quota,
12105            // quit right away without showing a crash dialog.
12106            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12107                Binder.restoreCallingIdentity(origId);
12108                return;
12109            }
12110
12111            Message msg = Message.obtain();
12112            msg.what = SHOW_ERROR_MSG;
12113            HashMap data = new HashMap();
12114            data.put("result", result);
12115            data.put("app", r);
12116            msg.obj = data;
12117            mHandler.sendMessage(msg);
12118
12119            Binder.restoreCallingIdentity(origId);
12120        }
12121
12122        int res = result.get();
12123
12124        Intent appErrorIntent = null;
12125        synchronized (this) {
12126            if (r != null && !r.isolated) {
12127                // XXX Can't keep track of crash time for isolated processes,
12128                // since they don't have a persistent identity.
12129                mProcessCrashTimes.put(r.info.processName, r.uid,
12130                        SystemClock.uptimeMillis());
12131            }
12132            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12133                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12134            }
12135        }
12136
12137        if (appErrorIntent != null) {
12138            try {
12139                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12140            } catch (ActivityNotFoundException e) {
12141                Slog.w(TAG, "bug report receiver dissappeared", e);
12142            }
12143        }
12144    }
12145
12146    Intent createAppErrorIntentLocked(ProcessRecord r,
12147            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12148        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12149        if (report == null) {
12150            return null;
12151        }
12152        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12153        result.setComponent(r.errorReportReceiver);
12154        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12155        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12156        return result;
12157    }
12158
12159    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12160            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12161        if (r.errorReportReceiver == null) {
12162            return null;
12163        }
12164
12165        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12166            return null;
12167        }
12168
12169        ApplicationErrorReport report = new ApplicationErrorReport();
12170        report.packageName = r.info.packageName;
12171        report.installerPackageName = r.errorReportReceiver.getPackageName();
12172        report.processName = r.processName;
12173        report.time = timeMillis;
12174        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12175
12176        if (r.crashing || r.forceCrashReport) {
12177            report.type = ApplicationErrorReport.TYPE_CRASH;
12178            report.crashInfo = crashInfo;
12179        } else if (r.notResponding) {
12180            report.type = ApplicationErrorReport.TYPE_ANR;
12181            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12182
12183            report.anrInfo.activity = r.notRespondingReport.tag;
12184            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12185            report.anrInfo.info = r.notRespondingReport.longMsg;
12186        }
12187
12188        return report;
12189    }
12190
12191    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12192        enforceNotIsolatedCaller("getProcessesInErrorState");
12193        // assume our apps are happy - lazy create the list
12194        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12195
12196        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12197                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12198        int userId = UserHandle.getUserId(Binder.getCallingUid());
12199
12200        synchronized (this) {
12201
12202            // iterate across all processes
12203            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12204                ProcessRecord app = mLruProcesses.get(i);
12205                if (!allUsers && app.userId != userId) {
12206                    continue;
12207                }
12208                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12209                    // This one's in trouble, so we'll generate a report for it
12210                    // crashes are higher priority (in case there's a crash *and* an anr)
12211                    ActivityManager.ProcessErrorStateInfo report = null;
12212                    if (app.crashing) {
12213                        report = app.crashingReport;
12214                    } else if (app.notResponding) {
12215                        report = app.notRespondingReport;
12216                    }
12217
12218                    if (report != null) {
12219                        if (errList == null) {
12220                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12221                        }
12222                        errList.add(report);
12223                    } else {
12224                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12225                                " crashing = " + app.crashing +
12226                                " notResponding = " + app.notResponding);
12227                    }
12228                }
12229            }
12230        }
12231
12232        return errList;
12233    }
12234
12235    static int procStateToImportance(int procState, int memAdj,
12236            ActivityManager.RunningAppProcessInfo currApp) {
12237        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12238        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12239            currApp.lru = memAdj;
12240        } else {
12241            currApp.lru = 0;
12242        }
12243        return imp;
12244    }
12245
12246    private void fillInProcMemInfo(ProcessRecord app,
12247            ActivityManager.RunningAppProcessInfo outInfo) {
12248        outInfo.pid = app.pid;
12249        outInfo.uid = app.info.uid;
12250        if (mHeavyWeightProcess == app) {
12251            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12252        }
12253        if (app.persistent) {
12254            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12255        }
12256        if (app.activities.size() > 0) {
12257            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12258        }
12259        outInfo.lastTrimLevel = app.trimMemoryLevel;
12260        int adj = app.curAdj;
12261        int procState = app.curProcState;
12262        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12263        outInfo.importanceReasonCode = app.adjTypeCode;
12264        outInfo.processState = app.curProcState;
12265    }
12266
12267    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12268        enforceNotIsolatedCaller("getRunningAppProcesses");
12269        // Lazy instantiation of list
12270        List<ActivityManager.RunningAppProcessInfo> runList = null;
12271        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12272                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12273        int userId = UserHandle.getUserId(Binder.getCallingUid());
12274        synchronized (this) {
12275            // Iterate across all processes
12276            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12277                ProcessRecord app = mLruProcesses.get(i);
12278                if (!allUsers && app.userId != userId) {
12279                    continue;
12280                }
12281                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12282                    // Generate process state info for running application
12283                    ActivityManager.RunningAppProcessInfo currApp =
12284                        new ActivityManager.RunningAppProcessInfo(app.processName,
12285                                app.pid, app.getPackageList());
12286                    fillInProcMemInfo(app, currApp);
12287                    if (app.adjSource instanceof ProcessRecord) {
12288                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12289                        currApp.importanceReasonImportance =
12290                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12291                                        app.adjSourceProcState);
12292                    } else if (app.adjSource instanceof ActivityRecord) {
12293                        ActivityRecord r = (ActivityRecord)app.adjSource;
12294                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12295                    }
12296                    if (app.adjTarget instanceof ComponentName) {
12297                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12298                    }
12299                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12300                    //        + " lru=" + currApp.lru);
12301                    if (runList == null) {
12302                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12303                    }
12304                    runList.add(currApp);
12305                }
12306            }
12307        }
12308        return runList;
12309    }
12310
12311    public List<ApplicationInfo> getRunningExternalApplications() {
12312        enforceNotIsolatedCaller("getRunningExternalApplications");
12313        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12314        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12315        if (runningApps != null && runningApps.size() > 0) {
12316            Set<String> extList = new HashSet<String>();
12317            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12318                if (app.pkgList != null) {
12319                    for (String pkg : app.pkgList) {
12320                        extList.add(pkg);
12321                    }
12322                }
12323            }
12324            IPackageManager pm = AppGlobals.getPackageManager();
12325            for (String pkg : extList) {
12326                try {
12327                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12328                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12329                        retList.add(info);
12330                    }
12331                } catch (RemoteException e) {
12332                }
12333            }
12334        }
12335        return retList;
12336    }
12337
12338    @Override
12339    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12340        enforceNotIsolatedCaller("getMyMemoryState");
12341        synchronized (this) {
12342            ProcessRecord proc;
12343            synchronized (mPidsSelfLocked) {
12344                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12345            }
12346            fillInProcMemInfo(proc, outInfo);
12347        }
12348    }
12349
12350    @Override
12351    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12352        if (checkCallingPermission(android.Manifest.permission.DUMP)
12353                != PackageManager.PERMISSION_GRANTED) {
12354            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12355                    + Binder.getCallingPid()
12356                    + ", uid=" + Binder.getCallingUid()
12357                    + " without permission "
12358                    + android.Manifest.permission.DUMP);
12359            return;
12360        }
12361
12362        boolean dumpAll = false;
12363        boolean dumpClient = false;
12364        String dumpPackage = null;
12365
12366        int opti = 0;
12367        while (opti < args.length) {
12368            String opt = args[opti];
12369            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12370                break;
12371            }
12372            opti++;
12373            if ("-a".equals(opt)) {
12374                dumpAll = true;
12375            } else if ("-c".equals(opt)) {
12376                dumpClient = true;
12377            } else if ("-h".equals(opt)) {
12378                pw.println("Activity manager dump options:");
12379                pw.println("  [-a] [-c] [-h] [cmd] ...");
12380                pw.println("  cmd may be one of:");
12381                pw.println("    a[ctivities]: activity stack state");
12382                pw.println("    r[recents]: recent activities state");
12383                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12384                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12385                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12386                pw.println("    o[om]: out of memory management");
12387                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12388                pw.println("    provider [COMP_SPEC]: provider client-side state");
12389                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12390                pw.println("    service [COMP_SPEC]: service client-side state");
12391                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12392                pw.println("    all: dump all activities");
12393                pw.println("    top: dump the top activity");
12394                pw.println("    write: write all pending state to storage");
12395                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12396                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12397                pw.println("    a partial substring in a component name, a");
12398                pw.println("    hex object identifier.");
12399                pw.println("  -a: include all available server state.");
12400                pw.println("  -c: include client state.");
12401                return;
12402            } else {
12403                pw.println("Unknown argument: " + opt + "; use -h for help");
12404            }
12405        }
12406
12407        long origId = Binder.clearCallingIdentity();
12408        boolean more = false;
12409        // Is the caller requesting to dump a particular piece of data?
12410        if (opti < args.length) {
12411            String cmd = args[opti];
12412            opti++;
12413            if ("activities".equals(cmd) || "a".equals(cmd)) {
12414                synchronized (this) {
12415                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12416                }
12417            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12418                synchronized (this) {
12419                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12420                }
12421            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12422                String[] newArgs;
12423                String name;
12424                if (opti >= args.length) {
12425                    name = null;
12426                    newArgs = EMPTY_STRING_ARRAY;
12427                } else {
12428                    name = args[opti];
12429                    opti++;
12430                    newArgs = new String[args.length - opti];
12431                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12432                            args.length - opti);
12433                }
12434                synchronized (this) {
12435                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12436                }
12437            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12438                String[] newArgs;
12439                String name;
12440                if (opti >= args.length) {
12441                    name = null;
12442                    newArgs = EMPTY_STRING_ARRAY;
12443                } else {
12444                    name = args[opti];
12445                    opti++;
12446                    newArgs = new String[args.length - opti];
12447                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12448                            args.length - opti);
12449                }
12450                synchronized (this) {
12451                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12452                }
12453            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12454                String[] newArgs;
12455                String name;
12456                if (opti >= args.length) {
12457                    name = null;
12458                    newArgs = EMPTY_STRING_ARRAY;
12459                } else {
12460                    name = args[opti];
12461                    opti++;
12462                    newArgs = new String[args.length - opti];
12463                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12464                            args.length - opti);
12465                }
12466                synchronized (this) {
12467                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12468                }
12469            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12470                synchronized (this) {
12471                    dumpOomLocked(fd, pw, args, opti, true);
12472                }
12473            } else if ("provider".equals(cmd)) {
12474                String[] newArgs;
12475                String name;
12476                if (opti >= args.length) {
12477                    name = null;
12478                    newArgs = EMPTY_STRING_ARRAY;
12479                } else {
12480                    name = args[opti];
12481                    opti++;
12482                    newArgs = new String[args.length - opti];
12483                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12484                }
12485                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12486                    pw.println("No providers match: " + name);
12487                    pw.println("Use -h for help.");
12488                }
12489            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12490                synchronized (this) {
12491                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12492                }
12493            } else if ("service".equals(cmd)) {
12494                String[] newArgs;
12495                String name;
12496                if (opti >= args.length) {
12497                    name = null;
12498                    newArgs = EMPTY_STRING_ARRAY;
12499                } else {
12500                    name = args[opti];
12501                    opti++;
12502                    newArgs = new String[args.length - opti];
12503                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12504                            args.length - opti);
12505                }
12506                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12507                    pw.println("No services match: " + name);
12508                    pw.println("Use -h for help.");
12509                }
12510            } else if ("package".equals(cmd)) {
12511                String[] newArgs;
12512                if (opti >= args.length) {
12513                    pw.println("package: no package name specified");
12514                    pw.println("Use -h for help.");
12515                } else {
12516                    dumpPackage = args[opti];
12517                    opti++;
12518                    newArgs = new String[args.length - opti];
12519                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12520                            args.length - opti);
12521                    args = newArgs;
12522                    opti = 0;
12523                    more = true;
12524                }
12525            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12526                synchronized (this) {
12527                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12528                }
12529            } else if ("write".equals(cmd)) {
12530                mTaskPersister.flush();
12531                pw.println("All tasks persisted.");
12532                return;
12533            } else {
12534                // Dumping a single activity?
12535                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12536                    pw.println("Bad activity command, or no activities match: " + cmd);
12537                    pw.println("Use -h for help.");
12538                }
12539            }
12540            if (!more) {
12541                Binder.restoreCallingIdentity(origId);
12542                return;
12543            }
12544        }
12545
12546        // No piece of data specified, dump everything.
12547        synchronized (this) {
12548            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12549            pw.println();
12550            if (dumpAll) {
12551                pw.println("-------------------------------------------------------------------------------");
12552            }
12553            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12554            pw.println();
12555            if (dumpAll) {
12556                pw.println("-------------------------------------------------------------------------------");
12557            }
12558            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12559            pw.println();
12560            if (dumpAll) {
12561                pw.println("-------------------------------------------------------------------------------");
12562            }
12563            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12564            pw.println();
12565            if (dumpAll) {
12566                pw.println("-------------------------------------------------------------------------------");
12567            }
12568            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12569            pw.println();
12570            if (dumpAll) {
12571                pw.println("-------------------------------------------------------------------------------");
12572            }
12573            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12574            pw.println();
12575            if (dumpAll) {
12576                pw.println("-------------------------------------------------------------------------------");
12577            }
12578            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12579        }
12580        Binder.restoreCallingIdentity(origId);
12581    }
12582
12583    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12584            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12585        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12586
12587        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12588                dumpPackage);
12589        boolean needSep = printedAnything;
12590
12591        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12592                dumpPackage, needSep, "  mFocusedActivity: ");
12593        if (printed) {
12594            printedAnything = true;
12595            needSep = false;
12596        }
12597
12598        if (dumpPackage == null) {
12599            if (needSep) {
12600                pw.println();
12601            }
12602            needSep = true;
12603            printedAnything = true;
12604            mStackSupervisor.dump(pw, "  ");
12605        }
12606
12607        if (!printedAnything) {
12608            pw.println("  (nothing)");
12609        }
12610    }
12611
12612    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12613            int opti, boolean dumpAll, String dumpPackage) {
12614        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12615
12616        boolean printedAnything = false;
12617
12618        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12619            boolean printedHeader = false;
12620
12621            final int N = mRecentTasks.size();
12622            for (int i=0; i<N; i++) {
12623                TaskRecord tr = mRecentTasks.get(i);
12624                if (dumpPackage != null) {
12625                    if (tr.realActivity == null ||
12626                            !dumpPackage.equals(tr.realActivity)) {
12627                        continue;
12628                    }
12629                }
12630                if (!printedHeader) {
12631                    pw.println("  Recent tasks:");
12632                    printedHeader = true;
12633                    printedAnything = true;
12634                }
12635                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12636                        pw.println(tr);
12637                if (dumpAll) {
12638                    mRecentTasks.get(i).dump(pw, "    ");
12639                }
12640            }
12641        }
12642
12643        if (!printedAnything) {
12644            pw.println("  (nothing)");
12645        }
12646    }
12647
12648    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12649            int opti, boolean dumpAll, String dumpPackage) {
12650        boolean needSep = false;
12651        boolean printedAnything = false;
12652        int numPers = 0;
12653
12654        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12655
12656        if (dumpAll) {
12657            final int NP = mProcessNames.getMap().size();
12658            for (int ip=0; ip<NP; ip++) {
12659                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12660                final int NA = procs.size();
12661                for (int ia=0; ia<NA; ia++) {
12662                    ProcessRecord r = procs.valueAt(ia);
12663                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12664                        continue;
12665                    }
12666                    if (!needSep) {
12667                        pw.println("  All known processes:");
12668                        needSep = true;
12669                        printedAnything = true;
12670                    }
12671                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12672                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12673                        pw.print(" "); pw.println(r);
12674                    r.dump(pw, "    ");
12675                    if (r.persistent) {
12676                        numPers++;
12677                    }
12678                }
12679            }
12680        }
12681
12682        if (mIsolatedProcesses.size() > 0) {
12683            boolean printed = false;
12684            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12685                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12686                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12687                    continue;
12688                }
12689                if (!printed) {
12690                    if (needSep) {
12691                        pw.println();
12692                    }
12693                    pw.println("  Isolated process list (sorted by uid):");
12694                    printedAnything = true;
12695                    printed = true;
12696                    needSep = true;
12697                }
12698                pw.println(String.format("%sIsolated #%2d: %s",
12699                        "    ", i, r.toString()));
12700            }
12701        }
12702
12703        if (mLruProcesses.size() > 0) {
12704            if (needSep) {
12705                pw.println();
12706            }
12707            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12708                    pw.print(" total, non-act at ");
12709                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12710                    pw.print(", non-svc at ");
12711                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12712                    pw.println("):");
12713            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12714            needSep = true;
12715            printedAnything = true;
12716        }
12717
12718        if (dumpAll || dumpPackage != null) {
12719            synchronized (mPidsSelfLocked) {
12720                boolean printed = false;
12721                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12722                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12723                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12724                        continue;
12725                    }
12726                    if (!printed) {
12727                        if (needSep) pw.println();
12728                        needSep = true;
12729                        pw.println("  PID mappings:");
12730                        printed = true;
12731                        printedAnything = true;
12732                    }
12733                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12734                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12735                }
12736            }
12737        }
12738
12739        if (mForegroundProcesses.size() > 0) {
12740            synchronized (mPidsSelfLocked) {
12741                boolean printed = false;
12742                for (int i=0; i<mForegroundProcesses.size(); i++) {
12743                    ProcessRecord r = mPidsSelfLocked.get(
12744                            mForegroundProcesses.valueAt(i).pid);
12745                    if (dumpPackage != null && (r == null
12746                            || !r.pkgList.containsKey(dumpPackage))) {
12747                        continue;
12748                    }
12749                    if (!printed) {
12750                        if (needSep) pw.println();
12751                        needSep = true;
12752                        pw.println("  Foreground Processes:");
12753                        printed = true;
12754                        printedAnything = true;
12755                    }
12756                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12757                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12758                }
12759            }
12760        }
12761
12762        if (mPersistentStartingProcesses.size() > 0) {
12763            if (needSep) pw.println();
12764            needSep = true;
12765            printedAnything = true;
12766            pw.println("  Persisent processes that are starting:");
12767            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12768                    "Starting Norm", "Restarting PERS", dumpPackage);
12769        }
12770
12771        if (mRemovedProcesses.size() > 0) {
12772            if (needSep) pw.println();
12773            needSep = true;
12774            printedAnything = true;
12775            pw.println("  Processes that are being removed:");
12776            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12777                    "Removed Norm", "Removed PERS", dumpPackage);
12778        }
12779
12780        if (mProcessesOnHold.size() > 0) {
12781            if (needSep) pw.println();
12782            needSep = true;
12783            printedAnything = true;
12784            pw.println("  Processes that are on old until the system is ready:");
12785            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12786                    "OnHold Norm", "OnHold PERS", dumpPackage);
12787        }
12788
12789        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12790
12791        if (mProcessCrashTimes.getMap().size() > 0) {
12792            boolean printed = false;
12793            long now = SystemClock.uptimeMillis();
12794            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12795            final int NP = pmap.size();
12796            for (int ip=0; ip<NP; ip++) {
12797                String pname = pmap.keyAt(ip);
12798                SparseArray<Long> uids = pmap.valueAt(ip);
12799                final int N = uids.size();
12800                for (int i=0; i<N; i++) {
12801                    int puid = uids.keyAt(i);
12802                    ProcessRecord r = mProcessNames.get(pname, puid);
12803                    if (dumpPackage != null && (r == null
12804                            || !r.pkgList.containsKey(dumpPackage))) {
12805                        continue;
12806                    }
12807                    if (!printed) {
12808                        if (needSep) pw.println();
12809                        needSep = true;
12810                        pw.println("  Time since processes crashed:");
12811                        printed = true;
12812                        printedAnything = true;
12813                    }
12814                    pw.print("    Process "); pw.print(pname);
12815                            pw.print(" uid "); pw.print(puid);
12816                            pw.print(": last crashed ");
12817                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12818                            pw.println(" ago");
12819                }
12820            }
12821        }
12822
12823        if (mBadProcesses.getMap().size() > 0) {
12824            boolean printed = false;
12825            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12826            final int NP = pmap.size();
12827            for (int ip=0; ip<NP; ip++) {
12828                String pname = pmap.keyAt(ip);
12829                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12830                final int N = uids.size();
12831                for (int i=0; i<N; i++) {
12832                    int puid = uids.keyAt(i);
12833                    ProcessRecord r = mProcessNames.get(pname, puid);
12834                    if (dumpPackage != null && (r == null
12835                            || !r.pkgList.containsKey(dumpPackage))) {
12836                        continue;
12837                    }
12838                    if (!printed) {
12839                        if (needSep) pw.println();
12840                        needSep = true;
12841                        pw.println("  Bad processes:");
12842                        printedAnything = true;
12843                    }
12844                    BadProcessInfo info = uids.valueAt(i);
12845                    pw.print("    Bad process "); pw.print(pname);
12846                            pw.print(" uid "); pw.print(puid);
12847                            pw.print(": crashed at time "); pw.println(info.time);
12848                    if (info.shortMsg != null) {
12849                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12850                    }
12851                    if (info.longMsg != null) {
12852                        pw.print("      Long msg: "); pw.println(info.longMsg);
12853                    }
12854                    if (info.stack != null) {
12855                        pw.println("      Stack:");
12856                        int lastPos = 0;
12857                        for (int pos=0; pos<info.stack.length(); pos++) {
12858                            if (info.stack.charAt(pos) == '\n') {
12859                                pw.print("        ");
12860                                pw.write(info.stack, lastPos, pos-lastPos);
12861                                pw.println();
12862                                lastPos = pos+1;
12863                            }
12864                        }
12865                        if (lastPos < info.stack.length()) {
12866                            pw.print("        ");
12867                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12868                            pw.println();
12869                        }
12870                    }
12871                }
12872            }
12873        }
12874
12875        if (dumpPackage == null) {
12876            pw.println();
12877            needSep = false;
12878            pw.println("  mStartedUsers:");
12879            for (int i=0; i<mStartedUsers.size(); i++) {
12880                UserStartedState uss = mStartedUsers.valueAt(i);
12881                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12882                        pw.print(": "); uss.dump("", pw);
12883            }
12884            pw.print("  mStartedUserArray: [");
12885            for (int i=0; i<mStartedUserArray.length; i++) {
12886                if (i > 0) pw.print(", ");
12887                pw.print(mStartedUserArray[i]);
12888            }
12889            pw.println("]");
12890            pw.print("  mUserLru: [");
12891            for (int i=0; i<mUserLru.size(); i++) {
12892                if (i > 0) pw.print(", ");
12893                pw.print(mUserLru.get(i));
12894            }
12895            pw.println("]");
12896            if (dumpAll) {
12897                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12898            }
12899            synchronized (mUserProfileGroupIdsSelfLocked) {
12900                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12901                    pw.println("  mUserProfileGroupIds:");
12902                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12903                        pw.print("    User #");
12904                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12905                        pw.print(" -> profile #");
12906                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12907                    }
12908                }
12909            }
12910        }
12911        if (mHomeProcess != null && (dumpPackage == null
12912                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12913            if (needSep) {
12914                pw.println();
12915                needSep = false;
12916            }
12917            pw.println("  mHomeProcess: " + mHomeProcess);
12918        }
12919        if (mPreviousProcess != null && (dumpPackage == null
12920                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12921            if (needSep) {
12922                pw.println();
12923                needSep = false;
12924            }
12925            pw.println("  mPreviousProcess: " + mPreviousProcess);
12926        }
12927        if (dumpAll) {
12928            StringBuilder sb = new StringBuilder(128);
12929            sb.append("  mPreviousProcessVisibleTime: ");
12930            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12931            pw.println(sb);
12932        }
12933        if (mHeavyWeightProcess != null && (dumpPackage == null
12934                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12935            if (needSep) {
12936                pw.println();
12937                needSep = false;
12938            }
12939            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12940        }
12941        if (dumpPackage == null) {
12942            pw.println("  mConfiguration: " + mConfiguration);
12943        }
12944        if (dumpAll) {
12945            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12946            if (mCompatModePackages.getPackages().size() > 0) {
12947                boolean printed = false;
12948                for (Map.Entry<String, Integer> entry
12949                        : mCompatModePackages.getPackages().entrySet()) {
12950                    String pkg = entry.getKey();
12951                    int mode = entry.getValue();
12952                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12953                        continue;
12954                    }
12955                    if (!printed) {
12956                        pw.println("  mScreenCompatPackages:");
12957                        printed = true;
12958                    }
12959                    pw.print("    "); pw.print(pkg); pw.print(": ");
12960                            pw.print(mode); pw.println();
12961                }
12962            }
12963        }
12964        if (dumpPackage == null) {
12965            if (mSleeping || mWentToSleep || mLockScreenShown) {
12966                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12967                        + " mLockScreenShown " + mLockScreenShown);
12968            }
12969            if (mShuttingDown || mRunningVoice) {
12970                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12971            }
12972        }
12973        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12974                || mOrigWaitForDebugger) {
12975            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12976                    || dumpPackage.equals(mOrigDebugApp)) {
12977                if (needSep) {
12978                    pw.println();
12979                    needSep = false;
12980                }
12981                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12982                        + " mDebugTransient=" + mDebugTransient
12983                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12984            }
12985        }
12986        if (mOpenGlTraceApp != null) {
12987            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12988                if (needSep) {
12989                    pw.println();
12990                    needSep = false;
12991                }
12992                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12993            }
12994        }
12995        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12996                || mProfileFd != null) {
12997            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12998                if (needSep) {
12999                    pw.println();
13000                    needSep = false;
13001                }
13002                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13003                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13004                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13005                        + mAutoStopProfiler);
13006                pw.println("  mProfileType=" + mProfileType);
13007            }
13008        }
13009        if (dumpPackage == null) {
13010            if (mAlwaysFinishActivities || mController != null) {
13011                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13012                        + " mController=" + mController);
13013            }
13014            if (dumpAll) {
13015                pw.println("  Total persistent processes: " + numPers);
13016                pw.println("  mProcessesReady=" + mProcessesReady
13017                        + " mSystemReady=" + mSystemReady
13018                        + " mBooted=" + mBooted
13019                        + " mFactoryTest=" + mFactoryTest);
13020                pw.println("  mBooting=" + mBooting
13021                        + " mCallFinishBooting=" + mCallFinishBooting
13022                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13023                pw.print("  mLastPowerCheckRealtime=");
13024                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13025                        pw.println("");
13026                pw.print("  mLastPowerCheckUptime=");
13027                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13028                        pw.println("");
13029                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13030                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13031                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13032                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13033                        + " (" + mLruProcesses.size() + " total)"
13034                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13035                        + " mNumServiceProcs=" + mNumServiceProcs
13036                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13037                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13038                        + " mLastMemoryLevel" + mLastMemoryLevel
13039                        + " mLastNumProcesses" + mLastNumProcesses);
13040                long now = SystemClock.uptimeMillis();
13041                pw.print("  mLastIdleTime=");
13042                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13043                        pw.print(" mLowRamSinceLastIdle=");
13044                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13045                        pw.println();
13046            }
13047        }
13048
13049        if (!printedAnything) {
13050            pw.println("  (nothing)");
13051        }
13052    }
13053
13054    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13055            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13056        if (mProcessesToGc.size() > 0) {
13057            boolean printed = false;
13058            long now = SystemClock.uptimeMillis();
13059            for (int i=0; i<mProcessesToGc.size(); i++) {
13060                ProcessRecord proc = mProcessesToGc.get(i);
13061                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13062                    continue;
13063                }
13064                if (!printed) {
13065                    if (needSep) pw.println();
13066                    needSep = true;
13067                    pw.println("  Processes that are waiting to GC:");
13068                    printed = true;
13069                }
13070                pw.print("    Process "); pw.println(proc);
13071                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13072                        pw.print(", last gced=");
13073                        pw.print(now-proc.lastRequestedGc);
13074                        pw.print(" ms ago, last lowMem=");
13075                        pw.print(now-proc.lastLowMemory);
13076                        pw.println(" ms ago");
13077
13078            }
13079        }
13080        return needSep;
13081    }
13082
13083    void printOomLevel(PrintWriter pw, String name, int adj) {
13084        pw.print("    ");
13085        if (adj >= 0) {
13086            pw.print(' ');
13087            if (adj < 10) pw.print(' ');
13088        } else {
13089            if (adj > -10) pw.print(' ');
13090        }
13091        pw.print(adj);
13092        pw.print(": ");
13093        pw.print(name);
13094        pw.print(" (");
13095        pw.print(mProcessList.getMemLevel(adj)/1024);
13096        pw.println(" kB)");
13097    }
13098
13099    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13100            int opti, boolean dumpAll) {
13101        boolean needSep = false;
13102
13103        if (mLruProcesses.size() > 0) {
13104            if (needSep) pw.println();
13105            needSep = true;
13106            pw.println("  OOM levels:");
13107            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13108            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13109            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13110            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13111            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13112            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13113            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13114            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13115            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13116            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13117            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13118            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13119            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13120            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13121
13122            if (needSep) pw.println();
13123            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13124                    pw.print(" total, non-act at ");
13125                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13126                    pw.print(", non-svc at ");
13127                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13128                    pw.println("):");
13129            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13130            needSep = true;
13131        }
13132
13133        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13134
13135        pw.println();
13136        pw.println("  mHomeProcess: " + mHomeProcess);
13137        pw.println("  mPreviousProcess: " + mPreviousProcess);
13138        if (mHeavyWeightProcess != null) {
13139            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13140        }
13141
13142        return true;
13143    }
13144
13145    /**
13146     * There are three ways to call this:
13147     *  - no provider specified: dump all the providers
13148     *  - a flattened component name that matched an existing provider was specified as the
13149     *    first arg: dump that one provider
13150     *  - the first arg isn't the flattened component name of an existing provider:
13151     *    dump all providers whose component contains the first arg as a substring
13152     */
13153    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13154            int opti, boolean dumpAll) {
13155        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13156    }
13157
13158    static class ItemMatcher {
13159        ArrayList<ComponentName> components;
13160        ArrayList<String> strings;
13161        ArrayList<Integer> objects;
13162        boolean all;
13163
13164        ItemMatcher() {
13165            all = true;
13166        }
13167
13168        void build(String name) {
13169            ComponentName componentName = ComponentName.unflattenFromString(name);
13170            if (componentName != null) {
13171                if (components == null) {
13172                    components = new ArrayList<ComponentName>();
13173                }
13174                components.add(componentName);
13175                all = false;
13176            } else {
13177                int objectId = 0;
13178                // Not a '/' separated full component name; maybe an object ID?
13179                try {
13180                    objectId = Integer.parseInt(name, 16);
13181                    if (objects == null) {
13182                        objects = new ArrayList<Integer>();
13183                    }
13184                    objects.add(objectId);
13185                    all = false;
13186                } catch (RuntimeException e) {
13187                    // Not an integer; just do string match.
13188                    if (strings == null) {
13189                        strings = new ArrayList<String>();
13190                    }
13191                    strings.add(name);
13192                    all = false;
13193                }
13194            }
13195        }
13196
13197        int build(String[] args, int opti) {
13198            for (; opti<args.length; opti++) {
13199                String name = args[opti];
13200                if ("--".equals(name)) {
13201                    return opti+1;
13202                }
13203                build(name);
13204            }
13205            return opti;
13206        }
13207
13208        boolean match(Object object, ComponentName comp) {
13209            if (all) {
13210                return true;
13211            }
13212            if (components != null) {
13213                for (int i=0; i<components.size(); i++) {
13214                    if (components.get(i).equals(comp)) {
13215                        return true;
13216                    }
13217                }
13218            }
13219            if (objects != null) {
13220                for (int i=0; i<objects.size(); i++) {
13221                    if (System.identityHashCode(object) == objects.get(i)) {
13222                        return true;
13223                    }
13224                }
13225            }
13226            if (strings != null) {
13227                String flat = comp.flattenToString();
13228                for (int i=0; i<strings.size(); i++) {
13229                    if (flat.contains(strings.get(i))) {
13230                        return true;
13231                    }
13232                }
13233            }
13234            return false;
13235        }
13236    }
13237
13238    /**
13239     * There are three things that cmd can be:
13240     *  - a flattened component name that matches an existing activity
13241     *  - the cmd arg isn't the flattened component name of an existing activity:
13242     *    dump all activity whose component contains the cmd as a substring
13243     *  - A hex number of the ActivityRecord object instance.
13244     */
13245    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13246            int opti, boolean dumpAll) {
13247        ArrayList<ActivityRecord> activities;
13248
13249        synchronized (this) {
13250            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13251        }
13252
13253        if (activities.size() <= 0) {
13254            return false;
13255        }
13256
13257        String[] newArgs = new String[args.length - opti];
13258        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13259
13260        TaskRecord lastTask = null;
13261        boolean needSep = false;
13262        for (int i=activities.size()-1; i>=0; i--) {
13263            ActivityRecord r = activities.get(i);
13264            if (needSep) {
13265                pw.println();
13266            }
13267            needSep = true;
13268            synchronized (this) {
13269                if (lastTask != r.task) {
13270                    lastTask = r.task;
13271                    pw.print("TASK "); pw.print(lastTask.affinity);
13272                            pw.print(" id="); pw.println(lastTask.taskId);
13273                    if (dumpAll) {
13274                        lastTask.dump(pw, "  ");
13275                    }
13276                }
13277            }
13278            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13279        }
13280        return true;
13281    }
13282
13283    /**
13284     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13285     * there is a thread associated with the activity.
13286     */
13287    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13288            final ActivityRecord r, String[] args, boolean dumpAll) {
13289        String innerPrefix = prefix + "  ";
13290        synchronized (this) {
13291            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13292                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13293                    pw.print(" pid=");
13294                    if (r.app != null) pw.println(r.app.pid);
13295                    else pw.println("(not running)");
13296            if (dumpAll) {
13297                r.dump(pw, innerPrefix);
13298            }
13299        }
13300        if (r.app != null && r.app.thread != null) {
13301            // flush anything that is already in the PrintWriter since the thread is going
13302            // to write to the file descriptor directly
13303            pw.flush();
13304            try {
13305                TransferPipe tp = new TransferPipe();
13306                try {
13307                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13308                            r.appToken, innerPrefix, args);
13309                    tp.go(fd);
13310                } finally {
13311                    tp.kill();
13312                }
13313            } catch (IOException e) {
13314                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13315            } catch (RemoteException e) {
13316                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13317            }
13318        }
13319    }
13320
13321    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13322            int opti, boolean dumpAll, String dumpPackage) {
13323        boolean needSep = false;
13324        boolean onlyHistory = false;
13325        boolean printedAnything = false;
13326
13327        if ("history".equals(dumpPackage)) {
13328            if (opti < args.length && "-s".equals(args[opti])) {
13329                dumpAll = false;
13330            }
13331            onlyHistory = true;
13332            dumpPackage = null;
13333        }
13334
13335        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13336        if (!onlyHistory && dumpAll) {
13337            if (mRegisteredReceivers.size() > 0) {
13338                boolean printed = false;
13339                Iterator it = mRegisteredReceivers.values().iterator();
13340                while (it.hasNext()) {
13341                    ReceiverList r = (ReceiverList)it.next();
13342                    if (dumpPackage != null && (r.app == null ||
13343                            !dumpPackage.equals(r.app.info.packageName))) {
13344                        continue;
13345                    }
13346                    if (!printed) {
13347                        pw.println("  Registered Receivers:");
13348                        needSep = true;
13349                        printed = true;
13350                        printedAnything = true;
13351                    }
13352                    pw.print("  * "); pw.println(r);
13353                    r.dump(pw, "    ");
13354                }
13355            }
13356
13357            if (mReceiverResolver.dump(pw, needSep ?
13358                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13359                    "    ", dumpPackage, false)) {
13360                needSep = true;
13361                printedAnything = true;
13362            }
13363        }
13364
13365        for (BroadcastQueue q : mBroadcastQueues) {
13366            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13367            printedAnything |= needSep;
13368        }
13369
13370        needSep = true;
13371
13372        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13373            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13374                if (needSep) {
13375                    pw.println();
13376                }
13377                needSep = true;
13378                printedAnything = true;
13379                pw.print("  Sticky broadcasts for user ");
13380                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13381                StringBuilder sb = new StringBuilder(128);
13382                for (Map.Entry<String, ArrayList<Intent>> ent
13383                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13384                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13385                    if (dumpAll) {
13386                        pw.println(":");
13387                        ArrayList<Intent> intents = ent.getValue();
13388                        final int N = intents.size();
13389                        for (int i=0; i<N; i++) {
13390                            sb.setLength(0);
13391                            sb.append("    Intent: ");
13392                            intents.get(i).toShortString(sb, false, true, false, false);
13393                            pw.println(sb.toString());
13394                            Bundle bundle = intents.get(i).getExtras();
13395                            if (bundle != null) {
13396                                pw.print("      ");
13397                                pw.println(bundle.toString());
13398                            }
13399                        }
13400                    } else {
13401                        pw.println("");
13402                    }
13403                }
13404            }
13405        }
13406
13407        if (!onlyHistory && dumpAll) {
13408            pw.println();
13409            for (BroadcastQueue queue : mBroadcastQueues) {
13410                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13411                        + queue.mBroadcastsScheduled);
13412            }
13413            pw.println("  mHandler:");
13414            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13415            needSep = true;
13416            printedAnything = true;
13417        }
13418
13419        if (!printedAnything) {
13420            pw.println("  (nothing)");
13421        }
13422    }
13423
13424    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13425            int opti, boolean dumpAll, String dumpPackage) {
13426        boolean needSep;
13427        boolean printedAnything = false;
13428
13429        ItemMatcher matcher = new ItemMatcher();
13430        matcher.build(args, opti);
13431
13432        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13433
13434        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13435        printedAnything |= needSep;
13436
13437        if (mLaunchingProviders.size() > 0) {
13438            boolean printed = false;
13439            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13440                ContentProviderRecord r = mLaunchingProviders.get(i);
13441                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13442                    continue;
13443                }
13444                if (!printed) {
13445                    if (needSep) pw.println();
13446                    needSep = true;
13447                    pw.println("  Launching content providers:");
13448                    printed = true;
13449                    printedAnything = true;
13450                }
13451                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13452                        pw.println(r);
13453            }
13454        }
13455
13456        if (mGrantedUriPermissions.size() > 0) {
13457            boolean printed = false;
13458            int dumpUid = -2;
13459            if (dumpPackage != null) {
13460                try {
13461                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13462                } catch (NameNotFoundException e) {
13463                    dumpUid = -1;
13464                }
13465            }
13466            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13467                int uid = mGrantedUriPermissions.keyAt(i);
13468                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13469                    continue;
13470                }
13471                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13472                if (!printed) {
13473                    if (needSep) pw.println();
13474                    needSep = true;
13475                    pw.println("  Granted Uri Permissions:");
13476                    printed = true;
13477                    printedAnything = true;
13478                }
13479                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13480                for (UriPermission perm : perms.values()) {
13481                    pw.print("    "); pw.println(perm);
13482                    if (dumpAll) {
13483                        perm.dump(pw, "      ");
13484                    }
13485                }
13486            }
13487        }
13488
13489        if (!printedAnything) {
13490            pw.println("  (nothing)");
13491        }
13492    }
13493
13494    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13495            int opti, boolean dumpAll, String dumpPackage) {
13496        boolean printed = false;
13497
13498        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13499
13500        if (mIntentSenderRecords.size() > 0) {
13501            Iterator<WeakReference<PendingIntentRecord>> it
13502                    = mIntentSenderRecords.values().iterator();
13503            while (it.hasNext()) {
13504                WeakReference<PendingIntentRecord> ref = it.next();
13505                PendingIntentRecord rec = ref != null ? ref.get(): null;
13506                if (dumpPackage != null && (rec == null
13507                        || !dumpPackage.equals(rec.key.packageName))) {
13508                    continue;
13509                }
13510                printed = true;
13511                if (rec != null) {
13512                    pw.print("  * "); pw.println(rec);
13513                    if (dumpAll) {
13514                        rec.dump(pw, "    ");
13515                    }
13516                } else {
13517                    pw.print("  * "); pw.println(ref);
13518                }
13519            }
13520        }
13521
13522        if (!printed) {
13523            pw.println("  (nothing)");
13524        }
13525    }
13526
13527    private static final int dumpProcessList(PrintWriter pw,
13528            ActivityManagerService service, List list,
13529            String prefix, String normalLabel, String persistentLabel,
13530            String dumpPackage) {
13531        int numPers = 0;
13532        final int N = list.size()-1;
13533        for (int i=N; i>=0; i--) {
13534            ProcessRecord r = (ProcessRecord)list.get(i);
13535            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13536                continue;
13537            }
13538            pw.println(String.format("%s%s #%2d: %s",
13539                    prefix, (r.persistent ? persistentLabel : normalLabel),
13540                    i, r.toString()));
13541            if (r.persistent) {
13542                numPers++;
13543            }
13544        }
13545        return numPers;
13546    }
13547
13548    private static final boolean dumpProcessOomList(PrintWriter pw,
13549            ActivityManagerService service, List<ProcessRecord> origList,
13550            String prefix, String normalLabel, String persistentLabel,
13551            boolean inclDetails, String dumpPackage) {
13552
13553        ArrayList<Pair<ProcessRecord, Integer>> list
13554                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13555        for (int i=0; i<origList.size(); i++) {
13556            ProcessRecord r = origList.get(i);
13557            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13558                continue;
13559            }
13560            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13561        }
13562
13563        if (list.size() <= 0) {
13564            return false;
13565        }
13566
13567        Comparator<Pair<ProcessRecord, Integer>> comparator
13568                = new Comparator<Pair<ProcessRecord, Integer>>() {
13569            @Override
13570            public int compare(Pair<ProcessRecord, Integer> object1,
13571                    Pair<ProcessRecord, Integer> object2) {
13572                if (object1.first.setAdj != object2.first.setAdj) {
13573                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13574                }
13575                if (object1.second.intValue() != object2.second.intValue()) {
13576                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13577                }
13578                return 0;
13579            }
13580        };
13581
13582        Collections.sort(list, comparator);
13583
13584        final long curRealtime = SystemClock.elapsedRealtime();
13585        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13586        final long curUptime = SystemClock.uptimeMillis();
13587        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13588
13589        for (int i=list.size()-1; i>=0; i--) {
13590            ProcessRecord r = list.get(i).first;
13591            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13592            char schedGroup;
13593            switch (r.setSchedGroup) {
13594                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13595                    schedGroup = 'B';
13596                    break;
13597                case Process.THREAD_GROUP_DEFAULT:
13598                    schedGroup = 'F';
13599                    break;
13600                default:
13601                    schedGroup = '?';
13602                    break;
13603            }
13604            char foreground;
13605            if (r.foregroundActivities) {
13606                foreground = 'A';
13607            } else if (r.foregroundServices) {
13608                foreground = 'S';
13609            } else {
13610                foreground = ' ';
13611            }
13612            String procState = ProcessList.makeProcStateString(r.curProcState);
13613            pw.print(prefix);
13614            pw.print(r.persistent ? persistentLabel : normalLabel);
13615            pw.print(" #");
13616            int num = (origList.size()-1)-list.get(i).second;
13617            if (num < 10) pw.print(' ');
13618            pw.print(num);
13619            pw.print(": ");
13620            pw.print(oomAdj);
13621            pw.print(' ');
13622            pw.print(schedGroup);
13623            pw.print('/');
13624            pw.print(foreground);
13625            pw.print('/');
13626            pw.print(procState);
13627            pw.print(" trm:");
13628            if (r.trimMemoryLevel < 10) pw.print(' ');
13629            pw.print(r.trimMemoryLevel);
13630            pw.print(' ');
13631            pw.print(r.toShortString());
13632            pw.print(" (");
13633            pw.print(r.adjType);
13634            pw.println(')');
13635            if (r.adjSource != null || r.adjTarget != null) {
13636                pw.print(prefix);
13637                pw.print("    ");
13638                if (r.adjTarget instanceof ComponentName) {
13639                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13640                } else if (r.adjTarget != null) {
13641                    pw.print(r.adjTarget.toString());
13642                } else {
13643                    pw.print("{null}");
13644                }
13645                pw.print("<=");
13646                if (r.adjSource instanceof ProcessRecord) {
13647                    pw.print("Proc{");
13648                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13649                    pw.println("}");
13650                } else if (r.adjSource != null) {
13651                    pw.println(r.adjSource.toString());
13652                } else {
13653                    pw.println("{null}");
13654                }
13655            }
13656            if (inclDetails) {
13657                pw.print(prefix);
13658                pw.print("    ");
13659                pw.print("oom: max="); pw.print(r.maxAdj);
13660                pw.print(" curRaw="); pw.print(r.curRawAdj);
13661                pw.print(" setRaw="); pw.print(r.setRawAdj);
13662                pw.print(" cur="); pw.print(r.curAdj);
13663                pw.print(" set="); pw.println(r.setAdj);
13664                pw.print(prefix);
13665                pw.print("    ");
13666                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13667                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13668                pw.print(" lastPss="); pw.print(r.lastPss);
13669                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13670                pw.print(prefix);
13671                pw.print("    ");
13672                pw.print("cached="); pw.print(r.cached);
13673                pw.print(" empty="); pw.print(r.empty);
13674                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13675
13676                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13677                    if (r.lastWakeTime != 0) {
13678                        long wtime;
13679                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13680                        synchronized (stats) {
13681                            wtime = stats.getProcessWakeTime(r.info.uid,
13682                                    r.pid, curRealtime);
13683                        }
13684                        long timeUsed = wtime - r.lastWakeTime;
13685                        pw.print(prefix);
13686                        pw.print("    ");
13687                        pw.print("keep awake over ");
13688                        TimeUtils.formatDuration(realtimeSince, pw);
13689                        pw.print(" used ");
13690                        TimeUtils.formatDuration(timeUsed, pw);
13691                        pw.print(" (");
13692                        pw.print((timeUsed*100)/realtimeSince);
13693                        pw.println("%)");
13694                    }
13695                    if (r.lastCpuTime != 0) {
13696                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13697                        pw.print(prefix);
13698                        pw.print("    ");
13699                        pw.print("run cpu over ");
13700                        TimeUtils.formatDuration(uptimeSince, pw);
13701                        pw.print(" used ");
13702                        TimeUtils.formatDuration(timeUsed, pw);
13703                        pw.print(" (");
13704                        pw.print((timeUsed*100)/uptimeSince);
13705                        pw.println("%)");
13706                    }
13707                }
13708            }
13709        }
13710        return true;
13711    }
13712
13713    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13714            String[] args) {
13715        ArrayList<ProcessRecord> procs;
13716        synchronized (this) {
13717            if (args != null && args.length > start
13718                    && args[start].charAt(0) != '-') {
13719                procs = new ArrayList<ProcessRecord>();
13720                int pid = -1;
13721                try {
13722                    pid = Integer.parseInt(args[start]);
13723                } catch (NumberFormatException e) {
13724                }
13725                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13726                    ProcessRecord proc = mLruProcesses.get(i);
13727                    if (proc.pid == pid) {
13728                        procs.add(proc);
13729                    } else if (allPkgs && proc.pkgList != null
13730                            && proc.pkgList.containsKey(args[start])) {
13731                        procs.add(proc);
13732                    } else if (proc.processName.equals(args[start])) {
13733                        procs.add(proc);
13734                    }
13735                }
13736                if (procs.size() <= 0) {
13737                    return null;
13738                }
13739            } else {
13740                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13741            }
13742        }
13743        return procs;
13744    }
13745
13746    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13747            PrintWriter pw, String[] args) {
13748        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13749        if (procs == null) {
13750            pw.println("No process found for: " + args[0]);
13751            return;
13752        }
13753
13754        long uptime = SystemClock.uptimeMillis();
13755        long realtime = SystemClock.elapsedRealtime();
13756        pw.println("Applications Graphics Acceleration Info:");
13757        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13758
13759        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13760            ProcessRecord r = procs.get(i);
13761            if (r.thread != null) {
13762                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13763                pw.flush();
13764                try {
13765                    TransferPipe tp = new TransferPipe();
13766                    try {
13767                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13768                        tp.go(fd);
13769                    } finally {
13770                        tp.kill();
13771                    }
13772                } catch (IOException e) {
13773                    pw.println("Failure while dumping the app: " + r);
13774                    pw.flush();
13775                } catch (RemoteException e) {
13776                    pw.println("Got a RemoteException while dumping the app " + r);
13777                    pw.flush();
13778                }
13779            }
13780        }
13781    }
13782
13783    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13784        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13785        if (procs == null) {
13786            pw.println("No process found for: " + args[0]);
13787            return;
13788        }
13789
13790        pw.println("Applications Database Info:");
13791
13792        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13793            ProcessRecord r = procs.get(i);
13794            if (r.thread != null) {
13795                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13796                pw.flush();
13797                try {
13798                    TransferPipe tp = new TransferPipe();
13799                    try {
13800                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13801                        tp.go(fd);
13802                    } finally {
13803                        tp.kill();
13804                    }
13805                } catch (IOException e) {
13806                    pw.println("Failure while dumping the app: " + r);
13807                    pw.flush();
13808                } catch (RemoteException e) {
13809                    pw.println("Got a RemoteException while dumping the app " + r);
13810                    pw.flush();
13811                }
13812            }
13813        }
13814    }
13815
13816    final static class MemItem {
13817        final boolean isProc;
13818        final String label;
13819        final String shortLabel;
13820        final long pss;
13821        final int id;
13822        final boolean hasActivities;
13823        ArrayList<MemItem> subitems;
13824
13825        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13826                boolean _hasActivities) {
13827            isProc = true;
13828            label = _label;
13829            shortLabel = _shortLabel;
13830            pss = _pss;
13831            id = _id;
13832            hasActivities = _hasActivities;
13833        }
13834
13835        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13836            isProc = false;
13837            label = _label;
13838            shortLabel = _shortLabel;
13839            pss = _pss;
13840            id = _id;
13841            hasActivities = false;
13842        }
13843    }
13844
13845    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13846            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13847        if (sort && !isCompact) {
13848            Collections.sort(items, new Comparator<MemItem>() {
13849                @Override
13850                public int compare(MemItem lhs, MemItem rhs) {
13851                    if (lhs.pss < rhs.pss) {
13852                        return 1;
13853                    } else if (lhs.pss > rhs.pss) {
13854                        return -1;
13855                    }
13856                    return 0;
13857                }
13858            });
13859        }
13860
13861        for (int i=0; i<items.size(); i++) {
13862            MemItem mi = items.get(i);
13863            if (!isCompact) {
13864                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13865            } else if (mi.isProc) {
13866                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13867                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13868                pw.println(mi.hasActivities ? ",a" : ",e");
13869            } else {
13870                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13871                pw.println(mi.pss);
13872            }
13873            if (mi.subitems != null) {
13874                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13875                        true, isCompact);
13876            }
13877        }
13878    }
13879
13880    // These are in KB.
13881    static final long[] DUMP_MEM_BUCKETS = new long[] {
13882        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13883        120*1024, 160*1024, 200*1024,
13884        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13885        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13886    };
13887
13888    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13889            boolean stackLike) {
13890        int start = label.lastIndexOf('.');
13891        if (start >= 0) start++;
13892        else start = 0;
13893        int end = label.length();
13894        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13895            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13896                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13897                out.append(bucket);
13898                out.append(stackLike ? "MB." : "MB ");
13899                out.append(label, start, end);
13900                return;
13901            }
13902        }
13903        out.append(memKB/1024);
13904        out.append(stackLike ? "MB." : "MB ");
13905        out.append(label, start, end);
13906    }
13907
13908    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13909            ProcessList.NATIVE_ADJ,
13910            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13911            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13912            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13913            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13914            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13915            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13916    };
13917    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13918            "Native",
13919            "System", "Persistent", "Persistent Service", "Foreground",
13920            "Visible", "Perceptible",
13921            "Heavy Weight", "Backup",
13922            "A Services", "Home",
13923            "Previous", "B Services", "Cached"
13924    };
13925    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13926            "native",
13927            "sys", "pers", "persvc", "fore",
13928            "vis", "percept",
13929            "heavy", "backup",
13930            "servicea", "home",
13931            "prev", "serviceb", "cached"
13932    };
13933
13934    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13935            long realtime, boolean isCheckinRequest, boolean isCompact) {
13936        if (isCheckinRequest || isCompact) {
13937            // short checkin version
13938            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13939        } else {
13940            pw.println("Applications Memory Usage (kB):");
13941            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13942        }
13943    }
13944
13945    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13946            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13947        boolean dumpDetails = false;
13948        boolean dumpFullDetails = false;
13949        boolean dumpDalvik = false;
13950        boolean oomOnly = false;
13951        boolean isCompact = false;
13952        boolean localOnly = false;
13953        boolean packages = false;
13954
13955        int opti = 0;
13956        while (opti < args.length) {
13957            String opt = args[opti];
13958            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13959                break;
13960            }
13961            opti++;
13962            if ("-a".equals(opt)) {
13963                dumpDetails = true;
13964                dumpFullDetails = true;
13965                dumpDalvik = true;
13966            } else if ("-d".equals(opt)) {
13967                dumpDalvik = true;
13968            } else if ("-c".equals(opt)) {
13969                isCompact = true;
13970            } else if ("--oom".equals(opt)) {
13971                oomOnly = true;
13972            } else if ("--local".equals(opt)) {
13973                localOnly = true;
13974            } else if ("--package".equals(opt)) {
13975                packages = true;
13976            } else if ("-h".equals(opt)) {
13977                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13978                pw.println("  -a: include all available information for each process.");
13979                pw.println("  -d: include dalvik details when dumping process details.");
13980                pw.println("  -c: dump in a compact machine-parseable representation.");
13981                pw.println("  --oom: only show processes organized by oom adj.");
13982                pw.println("  --local: only collect details locally, don't call process.");
13983                pw.println("  --package: interpret process arg as package, dumping all");
13984                pw.println("             processes that have loaded that package.");
13985                pw.println("If [process] is specified it can be the name or ");
13986                pw.println("pid of a specific process to dump.");
13987                return;
13988            } else {
13989                pw.println("Unknown argument: " + opt + "; use -h for help");
13990            }
13991        }
13992
13993        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13994        long uptime = SystemClock.uptimeMillis();
13995        long realtime = SystemClock.elapsedRealtime();
13996        final long[] tmpLong = new long[1];
13997
13998        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13999        if (procs == null) {
14000            // No Java processes.  Maybe they want to print a native process.
14001            if (args != null && args.length > opti
14002                    && args[opti].charAt(0) != '-') {
14003                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14004                        = new ArrayList<ProcessCpuTracker.Stats>();
14005                updateCpuStatsNow();
14006                int findPid = -1;
14007                try {
14008                    findPid = Integer.parseInt(args[opti]);
14009                } catch (NumberFormatException e) {
14010                }
14011                synchronized (mProcessCpuTracker) {
14012                    final int N = mProcessCpuTracker.countStats();
14013                    for (int i=0; i<N; i++) {
14014                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14015                        if (st.pid == findPid || (st.baseName != null
14016                                && st.baseName.equals(args[opti]))) {
14017                            nativeProcs.add(st);
14018                        }
14019                    }
14020                }
14021                if (nativeProcs.size() > 0) {
14022                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14023                            isCompact);
14024                    Debug.MemoryInfo mi = null;
14025                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14026                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14027                        final int pid = r.pid;
14028                        if (!isCheckinRequest && dumpDetails) {
14029                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14030                        }
14031                        if (mi == null) {
14032                            mi = new Debug.MemoryInfo();
14033                        }
14034                        if (dumpDetails || (!brief && !oomOnly)) {
14035                            Debug.getMemoryInfo(pid, mi);
14036                        } else {
14037                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14038                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14039                        }
14040                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14041                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14042                        if (isCheckinRequest) {
14043                            pw.println();
14044                        }
14045                    }
14046                    return;
14047                }
14048            }
14049            pw.println("No process found for: " + args[opti]);
14050            return;
14051        }
14052
14053        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14054            dumpDetails = true;
14055        }
14056
14057        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14058
14059        String[] innerArgs = new String[args.length-opti];
14060        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14061
14062        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14063        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14064        long nativePss=0, dalvikPss=0, otherPss=0;
14065        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14066
14067        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14068        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14069                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14070
14071        long totalPss = 0;
14072        long cachedPss = 0;
14073
14074        Debug.MemoryInfo mi = null;
14075        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14076            final ProcessRecord r = procs.get(i);
14077            final IApplicationThread thread;
14078            final int pid;
14079            final int oomAdj;
14080            final boolean hasActivities;
14081            synchronized (this) {
14082                thread = r.thread;
14083                pid = r.pid;
14084                oomAdj = r.getSetAdjWithServices();
14085                hasActivities = r.activities.size() > 0;
14086            }
14087            if (thread != null) {
14088                if (!isCheckinRequest && dumpDetails) {
14089                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14090                }
14091                if (mi == null) {
14092                    mi = new Debug.MemoryInfo();
14093                }
14094                if (dumpDetails || (!brief && !oomOnly)) {
14095                    Debug.getMemoryInfo(pid, mi);
14096                } else {
14097                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14098                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14099                }
14100                if (dumpDetails) {
14101                    if (localOnly) {
14102                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14103                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14104                        if (isCheckinRequest) {
14105                            pw.println();
14106                        }
14107                    } else {
14108                        try {
14109                            pw.flush();
14110                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14111                                    dumpDalvik, innerArgs);
14112                        } catch (RemoteException e) {
14113                            if (!isCheckinRequest) {
14114                                pw.println("Got RemoteException!");
14115                                pw.flush();
14116                            }
14117                        }
14118                    }
14119                }
14120
14121                final long myTotalPss = mi.getTotalPss();
14122                final long myTotalUss = mi.getTotalUss();
14123
14124                synchronized (this) {
14125                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14126                        // Record this for posterity if the process has been stable.
14127                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14128                    }
14129                }
14130
14131                if (!isCheckinRequest && mi != null) {
14132                    totalPss += myTotalPss;
14133                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14134                            (hasActivities ? " / activities)" : ")"),
14135                            r.processName, myTotalPss, pid, hasActivities);
14136                    procMems.add(pssItem);
14137                    procMemsMap.put(pid, pssItem);
14138
14139                    nativePss += mi.nativePss;
14140                    dalvikPss += mi.dalvikPss;
14141                    otherPss += mi.otherPss;
14142                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14143                        long mem = mi.getOtherPss(j);
14144                        miscPss[j] += mem;
14145                        otherPss -= mem;
14146                    }
14147
14148                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14149                        cachedPss += myTotalPss;
14150                    }
14151
14152                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14153                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14154                                || oomIndex == (oomPss.length-1)) {
14155                            oomPss[oomIndex] += myTotalPss;
14156                            if (oomProcs[oomIndex] == null) {
14157                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14158                            }
14159                            oomProcs[oomIndex].add(pssItem);
14160                            break;
14161                        }
14162                    }
14163                }
14164            }
14165        }
14166
14167        long nativeProcTotalPss = 0;
14168
14169        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14170            // If we are showing aggregations, also look for native processes to
14171            // include so that our aggregations are more accurate.
14172            updateCpuStatsNow();
14173            synchronized (mProcessCpuTracker) {
14174                final int N = mProcessCpuTracker.countStats();
14175                for (int i=0; i<N; i++) {
14176                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14177                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14178                        if (mi == null) {
14179                            mi = new Debug.MemoryInfo();
14180                        }
14181                        if (!brief && !oomOnly) {
14182                            Debug.getMemoryInfo(st.pid, mi);
14183                        } else {
14184                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14185                            mi.nativePrivateDirty = (int)tmpLong[0];
14186                        }
14187
14188                        final long myTotalPss = mi.getTotalPss();
14189                        totalPss += myTotalPss;
14190                        nativeProcTotalPss += myTotalPss;
14191
14192                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14193                                st.name, myTotalPss, st.pid, false);
14194                        procMems.add(pssItem);
14195
14196                        nativePss += mi.nativePss;
14197                        dalvikPss += mi.dalvikPss;
14198                        otherPss += mi.otherPss;
14199                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14200                            long mem = mi.getOtherPss(j);
14201                            miscPss[j] += mem;
14202                            otherPss -= mem;
14203                        }
14204                        oomPss[0] += myTotalPss;
14205                        if (oomProcs[0] == null) {
14206                            oomProcs[0] = new ArrayList<MemItem>();
14207                        }
14208                        oomProcs[0].add(pssItem);
14209                    }
14210                }
14211            }
14212
14213            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14214
14215            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14216            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14217            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14218            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14219                String label = Debug.MemoryInfo.getOtherLabel(j);
14220                catMems.add(new MemItem(label, label, miscPss[j], j));
14221            }
14222
14223            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14224            for (int j=0; j<oomPss.length; j++) {
14225                if (oomPss[j] != 0) {
14226                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14227                            : DUMP_MEM_OOM_LABEL[j];
14228                    MemItem item = new MemItem(label, label, oomPss[j],
14229                            DUMP_MEM_OOM_ADJ[j]);
14230                    item.subitems = oomProcs[j];
14231                    oomMems.add(item);
14232                }
14233            }
14234
14235            if (!brief && !oomOnly && !isCompact) {
14236                pw.println();
14237                pw.println("Total PSS by process:");
14238                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14239                pw.println();
14240            }
14241            if (!isCompact) {
14242                pw.println("Total PSS by OOM adjustment:");
14243            }
14244            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14245            if (!brief && !oomOnly) {
14246                PrintWriter out = categoryPw != null ? categoryPw : pw;
14247                if (!isCompact) {
14248                    out.println();
14249                    out.println("Total PSS by category:");
14250                }
14251                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14252            }
14253            if (!isCompact) {
14254                pw.println();
14255            }
14256            MemInfoReader memInfo = new MemInfoReader();
14257            memInfo.readMemInfo();
14258            if (nativeProcTotalPss > 0) {
14259                synchronized (this) {
14260                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14261                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14262                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14263                            nativeProcTotalPss);
14264                }
14265            }
14266            if (!brief) {
14267                if (!isCompact) {
14268                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14269                    pw.print(" kB (status ");
14270                    switch (mLastMemoryLevel) {
14271                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14272                            pw.println("normal)");
14273                            break;
14274                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14275                            pw.println("moderate)");
14276                            break;
14277                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14278                            pw.println("low)");
14279                            break;
14280                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14281                            pw.println("critical)");
14282                            break;
14283                        default:
14284                            pw.print(mLastMemoryLevel);
14285                            pw.println(")");
14286                            break;
14287                    }
14288                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14289                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14290                            pw.print(cachedPss); pw.print(" cached pss + ");
14291                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14292                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14293                } else {
14294                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14295                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14296                            + memInfo.getFreeSizeKb()); pw.print(",");
14297                    pw.println(totalPss - cachedPss);
14298                }
14299            }
14300            if (!isCompact) {
14301                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14302                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14303                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14304                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14305                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14306                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14307                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14308                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14309                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14310                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14311                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14312            }
14313            if (!brief) {
14314                if (memInfo.getZramTotalSizeKb() != 0) {
14315                    if (!isCompact) {
14316                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14317                                pw.print(" kB physical used for ");
14318                                pw.print(memInfo.getSwapTotalSizeKb()
14319                                        - memInfo.getSwapFreeSizeKb());
14320                                pw.print(" kB in swap (");
14321                                pw.print(memInfo.getSwapTotalSizeKb());
14322                                pw.println(" kB total swap)");
14323                    } else {
14324                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14325                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14326                                pw.println(memInfo.getSwapFreeSizeKb());
14327                    }
14328                }
14329                final int[] SINGLE_LONG_FORMAT = new int[] {
14330                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14331                };
14332                long[] longOut = new long[1];
14333                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14334                        SINGLE_LONG_FORMAT, null, longOut, null);
14335                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14336                longOut[0] = 0;
14337                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14338                        SINGLE_LONG_FORMAT, null, longOut, null);
14339                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14340                longOut[0] = 0;
14341                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14342                        SINGLE_LONG_FORMAT, null, longOut, null);
14343                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14344                longOut[0] = 0;
14345                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14346                        SINGLE_LONG_FORMAT, null, longOut, null);
14347                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14348                if (!isCompact) {
14349                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14350                        pw.print("      KSM: "); pw.print(sharing);
14351                                pw.print(" kB saved from shared ");
14352                                pw.print(shared); pw.println(" kB");
14353                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14354                                pw.print(voltile); pw.println(" kB volatile");
14355                    }
14356                    pw.print("   Tuning: ");
14357                    pw.print(ActivityManager.staticGetMemoryClass());
14358                    pw.print(" (large ");
14359                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14360                    pw.print("), oom ");
14361                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14362                    pw.print(" kB");
14363                    pw.print(", restore limit ");
14364                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14365                    pw.print(" kB");
14366                    if (ActivityManager.isLowRamDeviceStatic()) {
14367                        pw.print(" (low-ram)");
14368                    }
14369                    if (ActivityManager.isHighEndGfx()) {
14370                        pw.print(" (high-end-gfx)");
14371                    }
14372                    pw.println();
14373                } else {
14374                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14375                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14376                    pw.println(voltile);
14377                    pw.print("tuning,");
14378                    pw.print(ActivityManager.staticGetMemoryClass());
14379                    pw.print(',');
14380                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14381                    pw.print(',');
14382                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14383                    if (ActivityManager.isLowRamDeviceStatic()) {
14384                        pw.print(",low-ram");
14385                    }
14386                    if (ActivityManager.isHighEndGfx()) {
14387                        pw.print(",high-end-gfx");
14388                    }
14389                    pw.println();
14390                }
14391            }
14392        }
14393    }
14394
14395    /**
14396     * Searches array of arguments for the specified string
14397     * @param args array of argument strings
14398     * @param value value to search for
14399     * @return true if the value is contained in the array
14400     */
14401    private static boolean scanArgs(String[] args, String value) {
14402        if (args != null) {
14403            for (String arg : args) {
14404                if (value.equals(arg)) {
14405                    return true;
14406                }
14407            }
14408        }
14409        return false;
14410    }
14411
14412    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14413            ContentProviderRecord cpr, boolean always) {
14414        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14415
14416        if (!inLaunching || always) {
14417            synchronized (cpr) {
14418                cpr.launchingApp = null;
14419                cpr.notifyAll();
14420            }
14421            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14422            String names[] = cpr.info.authority.split(";");
14423            for (int j = 0; j < names.length; j++) {
14424                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14425            }
14426        }
14427
14428        for (int i=0; i<cpr.connections.size(); i++) {
14429            ContentProviderConnection conn = cpr.connections.get(i);
14430            if (conn.waiting) {
14431                // If this connection is waiting for the provider, then we don't
14432                // need to mess with its process unless we are always removing
14433                // or for some reason the provider is not currently launching.
14434                if (inLaunching && !always) {
14435                    continue;
14436                }
14437            }
14438            ProcessRecord capp = conn.client;
14439            conn.dead = true;
14440            if (conn.stableCount > 0) {
14441                if (!capp.persistent && capp.thread != null
14442                        && capp.pid != 0
14443                        && capp.pid != MY_PID) {
14444                    capp.kill("depends on provider "
14445                            + cpr.name.flattenToShortString()
14446                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14447                }
14448            } else if (capp.thread != null && conn.provider.provider != null) {
14449                try {
14450                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14451                } catch (RemoteException e) {
14452                }
14453                // In the protocol here, we don't expect the client to correctly
14454                // clean up this connection, we'll just remove it.
14455                cpr.connections.remove(i);
14456                conn.client.conProviders.remove(conn);
14457            }
14458        }
14459
14460        if (inLaunching && always) {
14461            mLaunchingProviders.remove(cpr);
14462        }
14463        return inLaunching;
14464    }
14465
14466    /**
14467     * Main code for cleaning up a process when it has gone away.  This is
14468     * called both as a result of the process dying, or directly when stopping
14469     * a process when running in single process mode.
14470     *
14471     * @return Returns true if the given process has been restarted, so the
14472     * app that was passed in must remain on the process lists.
14473     */
14474    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14475            boolean restarting, boolean allowRestart, int index) {
14476        if (index >= 0) {
14477            removeLruProcessLocked(app);
14478            ProcessList.remove(app.pid);
14479        }
14480
14481        mProcessesToGc.remove(app);
14482        mPendingPssProcesses.remove(app);
14483
14484        // Dismiss any open dialogs.
14485        if (app.crashDialog != null && !app.forceCrashReport) {
14486            app.crashDialog.dismiss();
14487            app.crashDialog = null;
14488        }
14489        if (app.anrDialog != null) {
14490            app.anrDialog.dismiss();
14491            app.anrDialog = null;
14492        }
14493        if (app.waitDialog != null) {
14494            app.waitDialog.dismiss();
14495            app.waitDialog = null;
14496        }
14497
14498        app.crashing = false;
14499        app.notResponding = false;
14500
14501        app.resetPackageList(mProcessStats);
14502        app.unlinkDeathRecipient();
14503        app.makeInactive(mProcessStats);
14504        app.waitingToKill = null;
14505        app.forcingToForeground = null;
14506        updateProcessForegroundLocked(app, false, false);
14507        app.foregroundActivities = false;
14508        app.hasShownUi = false;
14509        app.treatLikeActivity = false;
14510        app.hasAboveClient = false;
14511        app.hasClientActivities = false;
14512
14513        mServices.killServicesLocked(app, allowRestart);
14514
14515        boolean restart = false;
14516
14517        // Remove published content providers.
14518        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14519            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14520            final boolean always = app.bad || !allowRestart;
14521            if (removeDyingProviderLocked(app, cpr, always) || always) {
14522                // We left the provider in the launching list, need to
14523                // restart it.
14524                restart = true;
14525            }
14526
14527            cpr.provider = null;
14528            cpr.proc = null;
14529        }
14530        app.pubProviders.clear();
14531
14532        // Take care of any launching providers waiting for this process.
14533        if (checkAppInLaunchingProvidersLocked(app, false)) {
14534            restart = true;
14535        }
14536
14537        // Unregister from connected content providers.
14538        if (!app.conProviders.isEmpty()) {
14539            for (int i=0; i<app.conProviders.size(); i++) {
14540                ContentProviderConnection conn = app.conProviders.get(i);
14541                conn.provider.connections.remove(conn);
14542            }
14543            app.conProviders.clear();
14544        }
14545
14546        // At this point there may be remaining entries in mLaunchingProviders
14547        // where we were the only one waiting, so they are no longer of use.
14548        // Look for these and clean up if found.
14549        // XXX Commented out for now.  Trying to figure out a way to reproduce
14550        // the actual situation to identify what is actually going on.
14551        if (false) {
14552            for (int i=0; i<mLaunchingProviders.size(); i++) {
14553                ContentProviderRecord cpr = (ContentProviderRecord)
14554                        mLaunchingProviders.get(i);
14555                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14556                    synchronized (cpr) {
14557                        cpr.launchingApp = null;
14558                        cpr.notifyAll();
14559                    }
14560                }
14561            }
14562        }
14563
14564        skipCurrentReceiverLocked(app);
14565
14566        // Unregister any receivers.
14567        for (int i=app.receivers.size()-1; i>=0; i--) {
14568            removeReceiverLocked(app.receivers.valueAt(i));
14569        }
14570        app.receivers.clear();
14571
14572        // If the app is undergoing backup, tell the backup manager about it
14573        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14574            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14575                    + mBackupTarget.appInfo + " died during backup");
14576            try {
14577                IBackupManager bm = IBackupManager.Stub.asInterface(
14578                        ServiceManager.getService(Context.BACKUP_SERVICE));
14579                bm.agentDisconnected(app.info.packageName);
14580            } catch (RemoteException e) {
14581                // can't happen; backup manager is local
14582            }
14583        }
14584
14585        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14586            ProcessChangeItem item = mPendingProcessChanges.get(i);
14587            if (item.pid == app.pid) {
14588                mPendingProcessChanges.remove(i);
14589                mAvailProcessChanges.add(item);
14590            }
14591        }
14592        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14593
14594        // If the caller is restarting this app, then leave it in its
14595        // current lists and let the caller take care of it.
14596        if (restarting) {
14597            return false;
14598        }
14599
14600        if (!app.persistent || app.isolated) {
14601            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14602                    "Removing non-persistent process during cleanup: " + app);
14603            mProcessNames.remove(app.processName, app.uid);
14604            mIsolatedProcesses.remove(app.uid);
14605            if (mHeavyWeightProcess == app) {
14606                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14607                        mHeavyWeightProcess.userId, 0));
14608                mHeavyWeightProcess = null;
14609            }
14610        } else if (!app.removed) {
14611            // This app is persistent, so we need to keep its record around.
14612            // If it is not already on the pending app list, add it there
14613            // and start a new process for it.
14614            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14615                mPersistentStartingProcesses.add(app);
14616                restart = true;
14617            }
14618        }
14619        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14620                "Clean-up removing on hold: " + app);
14621        mProcessesOnHold.remove(app);
14622
14623        if (app == mHomeProcess) {
14624            mHomeProcess = null;
14625        }
14626        if (app == mPreviousProcess) {
14627            mPreviousProcess = null;
14628        }
14629
14630        if (restart && !app.isolated) {
14631            // We have components that still need to be running in the
14632            // process, so re-launch it.
14633            if (index < 0) {
14634                ProcessList.remove(app.pid);
14635            }
14636            mProcessNames.put(app.processName, app.uid, app);
14637            startProcessLocked(app, "restart", app.processName);
14638            return true;
14639        } else if (app.pid > 0 && app.pid != MY_PID) {
14640            // Goodbye!
14641            boolean removed;
14642            synchronized (mPidsSelfLocked) {
14643                mPidsSelfLocked.remove(app.pid);
14644                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14645            }
14646            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14647            if (app.isolated) {
14648                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14649            }
14650            app.setPid(0);
14651        }
14652        return false;
14653    }
14654
14655    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14656        // Look through the content providers we are waiting to have launched,
14657        // and if any run in this process then either schedule a restart of
14658        // the process or kill the client waiting for it if this process has
14659        // gone bad.
14660        int NL = mLaunchingProviders.size();
14661        boolean restart = false;
14662        for (int i=0; i<NL; i++) {
14663            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14664            if (cpr.launchingApp == app) {
14665                if (!alwaysBad && !app.bad) {
14666                    restart = true;
14667                } else {
14668                    removeDyingProviderLocked(app, cpr, true);
14669                    // cpr should have been removed from mLaunchingProviders
14670                    NL = mLaunchingProviders.size();
14671                    i--;
14672                }
14673            }
14674        }
14675        return restart;
14676    }
14677
14678    // =========================================================
14679    // SERVICES
14680    // =========================================================
14681
14682    @Override
14683    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14684            int flags) {
14685        enforceNotIsolatedCaller("getServices");
14686        synchronized (this) {
14687            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14688        }
14689    }
14690
14691    @Override
14692    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14693        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14694        synchronized (this) {
14695            return mServices.getRunningServiceControlPanelLocked(name);
14696        }
14697    }
14698
14699    @Override
14700    public ComponentName startService(IApplicationThread caller, Intent service,
14701            String resolvedType, int userId) {
14702        enforceNotIsolatedCaller("startService");
14703        // Refuse possible leaked file descriptors
14704        if (service != null && service.hasFileDescriptors() == true) {
14705            throw new IllegalArgumentException("File descriptors passed in Intent");
14706        }
14707
14708        if (DEBUG_SERVICE)
14709            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14710        synchronized(this) {
14711            final int callingPid = Binder.getCallingPid();
14712            final int callingUid = Binder.getCallingUid();
14713            final long origId = Binder.clearCallingIdentity();
14714            ComponentName res = mServices.startServiceLocked(caller, service,
14715                    resolvedType, callingPid, callingUid, userId);
14716            Binder.restoreCallingIdentity(origId);
14717            return res;
14718        }
14719    }
14720
14721    ComponentName startServiceInPackage(int uid,
14722            Intent service, String resolvedType, int userId) {
14723        synchronized(this) {
14724            if (DEBUG_SERVICE)
14725                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14726            final long origId = Binder.clearCallingIdentity();
14727            ComponentName res = mServices.startServiceLocked(null, service,
14728                    resolvedType, -1, uid, userId);
14729            Binder.restoreCallingIdentity(origId);
14730            return res;
14731        }
14732    }
14733
14734    @Override
14735    public int stopService(IApplicationThread caller, Intent service,
14736            String resolvedType, int userId) {
14737        enforceNotIsolatedCaller("stopService");
14738        // Refuse possible leaked file descriptors
14739        if (service != null && service.hasFileDescriptors() == true) {
14740            throw new IllegalArgumentException("File descriptors passed in Intent");
14741        }
14742
14743        synchronized(this) {
14744            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14745        }
14746    }
14747
14748    @Override
14749    public IBinder peekService(Intent service, String resolvedType) {
14750        enforceNotIsolatedCaller("peekService");
14751        // Refuse possible leaked file descriptors
14752        if (service != null && service.hasFileDescriptors() == true) {
14753            throw new IllegalArgumentException("File descriptors passed in Intent");
14754        }
14755        synchronized(this) {
14756            return mServices.peekServiceLocked(service, resolvedType);
14757        }
14758    }
14759
14760    @Override
14761    public boolean stopServiceToken(ComponentName className, IBinder token,
14762            int startId) {
14763        synchronized(this) {
14764            return mServices.stopServiceTokenLocked(className, token, startId);
14765        }
14766    }
14767
14768    @Override
14769    public void setServiceForeground(ComponentName className, IBinder token,
14770            int id, Notification notification, boolean removeNotification) {
14771        synchronized(this) {
14772            mServices.setServiceForegroundLocked(className, token, id, notification,
14773                    removeNotification);
14774        }
14775    }
14776
14777    @Override
14778    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14779            boolean requireFull, String name, String callerPackage) {
14780        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14781                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14782    }
14783
14784    int unsafeConvertIncomingUser(int userId) {
14785        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14786                ? mCurrentUserId : userId;
14787    }
14788
14789    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14790            int allowMode, String name, String callerPackage) {
14791        final int callingUserId = UserHandle.getUserId(callingUid);
14792        if (callingUserId == userId) {
14793            return userId;
14794        }
14795
14796        // Note that we may be accessing mCurrentUserId outside of a lock...
14797        // shouldn't be a big deal, if this is being called outside
14798        // of a locked context there is intrinsically a race with
14799        // the value the caller will receive and someone else changing it.
14800        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14801        // we will switch to the calling user if access to the current user fails.
14802        int targetUserId = unsafeConvertIncomingUser(userId);
14803
14804        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14805            final boolean allow;
14806            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14807                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14808                // If the caller has this permission, they always pass go.  And collect $200.
14809                allow = true;
14810            } else if (allowMode == ALLOW_FULL_ONLY) {
14811                // We require full access, sucks to be you.
14812                allow = false;
14813            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14814                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14815                // If the caller does not have either permission, they are always doomed.
14816                allow = false;
14817            } else if (allowMode == ALLOW_NON_FULL) {
14818                // We are blanket allowing non-full access, you lucky caller!
14819                allow = true;
14820            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14821                // We may or may not allow this depending on whether the two users are
14822                // in the same profile.
14823                synchronized (mUserProfileGroupIdsSelfLocked) {
14824                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14825                            UserInfo.NO_PROFILE_GROUP_ID);
14826                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14827                            UserInfo.NO_PROFILE_GROUP_ID);
14828                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14829                            && callingProfile == targetProfile;
14830                }
14831            } else {
14832                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14833            }
14834            if (!allow) {
14835                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14836                    // In this case, they would like to just execute as their
14837                    // owner user instead of failing.
14838                    targetUserId = callingUserId;
14839                } else {
14840                    StringBuilder builder = new StringBuilder(128);
14841                    builder.append("Permission Denial: ");
14842                    builder.append(name);
14843                    if (callerPackage != null) {
14844                        builder.append(" from ");
14845                        builder.append(callerPackage);
14846                    }
14847                    builder.append(" asks to run as user ");
14848                    builder.append(userId);
14849                    builder.append(" but is calling from user ");
14850                    builder.append(UserHandle.getUserId(callingUid));
14851                    builder.append("; this requires ");
14852                    builder.append(INTERACT_ACROSS_USERS_FULL);
14853                    if (allowMode != ALLOW_FULL_ONLY) {
14854                        builder.append(" or ");
14855                        builder.append(INTERACT_ACROSS_USERS);
14856                    }
14857                    String msg = builder.toString();
14858                    Slog.w(TAG, msg);
14859                    throw new SecurityException(msg);
14860                }
14861            }
14862        }
14863        if (!allowAll && targetUserId < 0) {
14864            throw new IllegalArgumentException(
14865                    "Call does not support special user #" + targetUserId);
14866        }
14867        // Check shell permission
14868        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14869            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14870                    targetUserId)) {
14871                throw new SecurityException("Shell does not have permission to access user "
14872                        + targetUserId + "\n " + Debug.getCallers(3));
14873            }
14874        }
14875        return targetUserId;
14876    }
14877
14878    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14879            String className, int flags) {
14880        boolean result = false;
14881        // For apps that don't have pre-defined UIDs, check for permission
14882        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14883            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14884                if (ActivityManager.checkUidPermission(
14885                        INTERACT_ACROSS_USERS,
14886                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14887                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14888                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14889                            + " requests FLAG_SINGLE_USER, but app does not hold "
14890                            + INTERACT_ACROSS_USERS;
14891                    Slog.w(TAG, msg);
14892                    throw new SecurityException(msg);
14893                }
14894                // Permission passed
14895                result = true;
14896            }
14897        } else if ("system".equals(componentProcessName)) {
14898            result = true;
14899        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14900            // Phone app and persistent apps are allowed to export singleuser providers.
14901            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14902                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14903        }
14904        if (DEBUG_MU) {
14905            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14906                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14907        }
14908        return result;
14909    }
14910
14911    /**
14912     * Checks to see if the caller is in the same app as the singleton
14913     * component, or the component is in a special app. It allows special apps
14914     * to export singleton components but prevents exporting singleton
14915     * components for regular apps.
14916     */
14917    boolean isValidSingletonCall(int callingUid, int componentUid) {
14918        int componentAppId = UserHandle.getAppId(componentUid);
14919        return UserHandle.isSameApp(callingUid, componentUid)
14920                || componentAppId == Process.SYSTEM_UID
14921                || componentAppId == Process.PHONE_UID
14922                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14923                        == PackageManager.PERMISSION_GRANTED;
14924    }
14925
14926    public int bindService(IApplicationThread caller, IBinder token,
14927            Intent service, String resolvedType,
14928            IServiceConnection connection, int flags, int userId) {
14929        enforceNotIsolatedCaller("bindService");
14930
14931        // Refuse possible leaked file descriptors
14932        if (service != null && service.hasFileDescriptors() == true) {
14933            throw new IllegalArgumentException("File descriptors passed in Intent");
14934        }
14935
14936        synchronized(this) {
14937            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14938                    connection, flags, userId);
14939        }
14940    }
14941
14942    public boolean unbindService(IServiceConnection connection) {
14943        synchronized (this) {
14944            return mServices.unbindServiceLocked(connection);
14945        }
14946    }
14947
14948    public void publishService(IBinder token, Intent intent, IBinder service) {
14949        // Refuse possible leaked file descriptors
14950        if (intent != null && intent.hasFileDescriptors() == true) {
14951            throw new IllegalArgumentException("File descriptors passed in Intent");
14952        }
14953
14954        synchronized(this) {
14955            if (!(token instanceof ServiceRecord)) {
14956                throw new IllegalArgumentException("Invalid service token");
14957            }
14958            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14959        }
14960    }
14961
14962    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14963        // Refuse possible leaked file descriptors
14964        if (intent != null && intent.hasFileDescriptors() == true) {
14965            throw new IllegalArgumentException("File descriptors passed in Intent");
14966        }
14967
14968        synchronized(this) {
14969            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14970        }
14971    }
14972
14973    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14974        synchronized(this) {
14975            if (!(token instanceof ServiceRecord)) {
14976                throw new IllegalArgumentException("Invalid service token");
14977            }
14978            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14979        }
14980    }
14981
14982    // =========================================================
14983    // BACKUP AND RESTORE
14984    // =========================================================
14985
14986    // Cause the target app to be launched if necessary and its backup agent
14987    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14988    // activity manager to announce its creation.
14989    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14990        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14991        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14992
14993        synchronized(this) {
14994            // !!! TODO: currently no check here that we're already bound
14995            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14996            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14997            synchronized (stats) {
14998                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14999            }
15000
15001            // Backup agent is now in use, its package can't be stopped.
15002            try {
15003                AppGlobals.getPackageManager().setPackageStoppedState(
15004                        app.packageName, false, UserHandle.getUserId(app.uid));
15005            } catch (RemoteException e) {
15006            } catch (IllegalArgumentException e) {
15007                Slog.w(TAG, "Failed trying to unstop package "
15008                        + app.packageName + ": " + e);
15009            }
15010
15011            BackupRecord r = new BackupRecord(ss, app, backupMode);
15012            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15013                    ? new ComponentName(app.packageName, app.backupAgentName)
15014                    : new ComponentName("android", "FullBackupAgent");
15015            // startProcessLocked() returns existing proc's record if it's already running
15016            ProcessRecord proc = startProcessLocked(app.processName, app,
15017                    false, 0, "backup", hostingName, false, false, false);
15018            if (proc == null) {
15019                Slog.e(TAG, "Unable to start backup agent process " + r);
15020                return false;
15021            }
15022
15023            r.app = proc;
15024            mBackupTarget = r;
15025            mBackupAppName = app.packageName;
15026
15027            // Try not to kill the process during backup
15028            updateOomAdjLocked(proc);
15029
15030            // If the process is already attached, schedule the creation of the backup agent now.
15031            // If it is not yet live, this will be done when it attaches to the framework.
15032            if (proc.thread != null) {
15033                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15034                try {
15035                    proc.thread.scheduleCreateBackupAgent(app,
15036                            compatibilityInfoForPackageLocked(app), backupMode);
15037                } catch (RemoteException e) {
15038                    // Will time out on the backup manager side
15039                }
15040            } else {
15041                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15042            }
15043            // Invariants: at this point, the target app process exists and the application
15044            // is either already running or in the process of coming up.  mBackupTarget and
15045            // mBackupAppName describe the app, so that when it binds back to the AM we
15046            // know that it's scheduled for a backup-agent operation.
15047        }
15048
15049        return true;
15050    }
15051
15052    @Override
15053    public void clearPendingBackup() {
15054        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15055        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15056
15057        synchronized (this) {
15058            mBackupTarget = null;
15059            mBackupAppName = null;
15060        }
15061    }
15062
15063    // A backup agent has just come up
15064    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15065        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15066                + " = " + agent);
15067
15068        synchronized(this) {
15069            if (!agentPackageName.equals(mBackupAppName)) {
15070                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15071                return;
15072            }
15073        }
15074
15075        long oldIdent = Binder.clearCallingIdentity();
15076        try {
15077            IBackupManager bm = IBackupManager.Stub.asInterface(
15078                    ServiceManager.getService(Context.BACKUP_SERVICE));
15079            bm.agentConnected(agentPackageName, agent);
15080        } catch (RemoteException e) {
15081            // can't happen; the backup manager service is local
15082        } catch (Exception e) {
15083            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15084            e.printStackTrace();
15085        } finally {
15086            Binder.restoreCallingIdentity(oldIdent);
15087        }
15088    }
15089
15090    // done with this agent
15091    public void unbindBackupAgent(ApplicationInfo appInfo) {
15092        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15093        if (appInfo == null) {
15094            Slog.w(TAG, "unbind backup agent for null app");
15095            return;
15096        }
15097
15098        synchronized(this) {
15099            try {
15100                if (mBackupAppName == null) {
15101                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15102                    return;
15103                }
15104
15105                if (!mBackupAppName.equals(appInfo.packageName)) {
15106                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15107                    return;
15108                }
15109
15110                // Not backing this app up any more; reset its OOM adjustment
15111                final ProcessRecord proc = mBackupTarget.app;
15112                updateOomAdjLocked(proc);
15113
15114                // If the app crashed during backup, 'thread' will be null here
15115                if (proc.thread != null) {
15116                    try {
15117                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15118                                compatibilityInfoForPackageLocked(appInfo));
15119                    } catch (Exception e) {
15120                        Slog.e(TAG, "Exception when unbinding backup agent:");
15121                        e.printStackTrace();
15122                    }
15123                }
15124            } finally {
15125                mBackupTarget = null;
15126                mBackupAppName = null;
15127            }
15128        }
15129    }
15130    // =========================================================
15131    // BROADCASTS
15132    // =========================================================
15133
15134    private final List getStickiesLocked(String action, IntentFilter filter,
15135            List cur, int userId) {
15136        final ContentResolver resolver = mContext.getContentResolver();
15137        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15138        if (stickies == null) {
15139            return cur;
15140        }
15141        final ArrayList<Intent> list = stickies.get(action);
15142        if (list == null) {
15143            return cur;
15144        }
15145        int N = list.size();
15146        for (int i=0; i<N; i++) {
15147            Intent intent = list.get(i);
15148            if (filter.match(resolver, intent, true, TAG) >= 0) {
15149                if (cur == null) {
15150                    cur = new ArrayList<Intent>();
15151                }
15152                cur.add(intent);
15153            }
15154        }
15155        return cur;
15156    }
15157
15158    boolean isPendingBroadcastProcessLocked(int pid) {
15159        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15160                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15161    }
15162
15163    void skipPendingBroadcastLocked(int pid) {
15164            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15165            for (BroadcastQueue queue : mBroadcastQueues) {
15166                queue.skipPendingBroadcastLocked(pid);
15167            }
15168    }
15169
15170    // The app just attached; send any pending broadcasts that it should receive
15171    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15172        boolean didSomething = false;
15173        for (BroadcastQueue queue : mBroadcastQueues) {
15174            didSomething |= queue.sendPendingBroadcastsLocked(app);
15175        }
15176        return didSomething;
15177    }
15178
15179    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15180            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15181        enforceNotIsolatedCaller("registerReceiver");
15182        int callingUid;
15183        int callingPid;
15184        synchronized(this) {
15185            ProcessRecord callerApp = null;
15186            if (caller != null) {
15187                callerApp = getRecordForAppLocked(caller);
15188                if (callerApp == null) {
15189                    throw new SecurityException(
15190                            "Unable to find app for caller " + caller
15191                            + " (pid=" + Binder.getCallingPid()
15192                            + ") when registering receiver " + receiver);
15193                }
15194                if (callerApp.info.uid != Process.SYSTEM_UID &&
15195                        !callerApp.pkgList.containsKey(callerPackage) &&
15196                        !"android".equals(callerPackage)) {
15197                    throw new SecurityException("Given caller package " + callerPackage
15198                            + " is not running in process " + callerApp);
15199                }
15200                callingUid = callerApp.info.uid;
15201                callingPid = callerApp.pid;
15202            } else {
15203                callerPackage = null;
15204                callingUid = Binder.getCallingUid();
15205                callingPid = Binder.getCallingPid();
15206            }
15207
15208            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15209                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15210
15211            List allSticky = null;
15212
15213            // Look for any matching sticky broadcasts...
15214            Iterator actions = filter.actionsIterator();
15215            if (actions != null) {
15216                while (actions.hasNext()) {
15217                    String action = (String)actions.next();
15218                    allSticky = getStickiesLocked(action, filter, allSticky,
15219                            UserHandle.USER_ALL);
15220                    allSticky = getStickiesLocked(action, filter, allSticky,
15221                            UserHandle.getUserId(callingUid));
15222                }
15223            } else {
15224                allSticky = getStickiesLocked(null, filter, allSticky,
15225                        UserHandle.USER_ALL);
15226                allSticky = getStickiesLocked(null, filter, allSticky,
15227                        UserHandle.getUserId(callingUid));
15228            }
15229
15230            // The first sticky in the list is returned directly back to
15231            // the client.
15232            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15233
15234            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15235                    + ": " + sticky);
15236
15237            if (receiver == null) {
15238                return sticky;
15239            }
15240
15241            ReceiverList rl
15242                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15243            if (rl == null) {
15244                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15245                        userId, receiver);
15246                if (rl.app != null) {
15247                    rl.app.receivers.add(rl);
15248                } else {
15249                    try {
15250                        receiver.asBinder().linkToDeath(rl, 0);
15251                    } catch (RemoteException e) {
15252                        return sticky;
15253                    }
15254                    rl.linkedToDeath = true;
15255                }
15256                mRegisteredReceivers.put(receiver.asBinder(), rl);
15257            } else if (rl.uid != callingUid) {
15258                throw new IllegalArgumentException(
15259                        "Receiver requested to register for uid " + callingUid
15260                        + " was previously registered for uid " + rl.uid);
15261            } else if (rl.pid != callingPid) {
15262                throw new IllegalArgumentException(
15263                        "Receiver requested to register for pid " + callingPid
15264                        + " was previously registered for pid " + rl.pid);
15265            } else if (rl.userId != userId) {
15266                throw new IllegalArgumentException(
15267                        "Receiver requested to register for user " + userId
15268                        + " was previously registered for user " + rl.userId);
15269            }
15270            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15271                    permission, callingUid, userId);
15272            rl.add(bf);
15273            if (!bf.debugCheck()) {
15274                Slog.w(TAG, "==> For Dynamic broadast");
15275            }
15276            mReceiverResolver.addFilter(bf);
15277
15278            // Enqueue broadcasts for all existing stickies that match
15279            // this filter.
15280            if (allSticky != null) {
15281                ArrayList receivers = new ArrayList();
15282                receivers.add(bf);
15283
15284                int N = allSticky.size();
15285                for (int i=0; i<N; i++) {
15286                    Intent intent = (Intent)allSticky.get(i);
15287                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15288                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15289                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15290                            null, null, false, true, true, -1);
15291                    queue.enqueueParallelBroadcastLocked(r);
15292                    queue.scheduleBroadcastsLocked();
15293                }
15294            }
15295
15296            return sticky;
15297        }
15298    }
15299
15300    public void unregisterReceiver(IIntentReceiver receiver) {
15301        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15302
15303        final long origId = Binder.clearCallingIdentity();
15304        try {
15305            boolean doTrim = false;
15306
15307            synchronized(this) {
15308                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15309                if (rl != null) {
15310                    if (rl.curBroadcast != null) {
15311                        BroadcastRecord r = rl.curBroadcast;
15312                        final boolean doNext = finishReceiverLocked(
15313                                receiver.asBinder(), r.resultCode, r.resultData,
15314                                r.resultExtras, r.resultAbort);
15315                        if (doNext) {
15316                            doTrim = true;
15317                            r.queue.processNextBroadcast(false);
15318                        }
15319                    }
15320
15321                    if (rl.app != null) {
15322                        rl.app.receivers.remove(rl);
15323                    }
15324                    removeReceiverLocked(rl);
15325                    if (rl.linkedToDeath) {
15326                        rl.linkedToDeath = false;
15327                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15328                    }
15329                }
15330            }
15331
15332            // If we actually concluded any broadcasts, we might now be able
15333            // to trim the recipients' apps from our working set
15334            if (doTrim) {
15335                trimApplications();
15336                return;
15337            }
15338
15339        } finally {
15340            Binder.restoreCallingIdentity(origId);
15341        }
15342    }
15343
15344    void removeReceiverLocked(ReceiverList rl) {
15345        mRegisteredReceivers.remove(rl.receiver.asBinder());
15346        int N = rl.size();
15347        for (int i=0; i<N; i++) {
15348            mReceiverResolver.removeFilter(rl.get(i));
15349        }
15350    }
15351
15352    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15353        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15354            ProcessRecord r = mLruProcesses.get(i);
15355            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15356                try {
15357                    r.thread.dispatchPackageBroadcast(cmd, packages);
15358                } catch (RemoteException ex) {
15359                }
15360            }
15361        }
15362    }
15363
15364    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15365            int callingUid, int[] users) {
15366        List<ResolveInfo> receivers = null;
15367        try {
15368            HashSet<ComponentName> singleUserReceivers = null;
15369            boolean scannedFirstReceivers = false;
15370            for (int user : users) {
15371                // Skip users that have Shell restrictions
15372                if (callingUid == Process.SHELL_UID
15373                        && getUserManagerLocked().hasUserRestriction(
15374                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15375                    continue;
15376                }
15377                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15378                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15379                if (user != 0 && newReceivers != null) {
15380                    // If this is not the primary user, we need to check for
15381                    // any receivers that should be filtered out.
15382                    for (int i=0; i<newReceivers.size(); i++) {
15383                        ResolveInfo ri = newReceivers.get(i);
15384                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15385                            newReceivers.remove(i);
15386                            i--;
15387                        }
15388                    }
15389                }
15390                if (newReceivers != null && newReceivers.size() == 0) {
15391                    newReceivers = null;
15392                }
15393                if (receivers == null) {
15394                    receivers = newReceivers;
15395                } else if (newReceivers != null) {
15396                    // We need to concatenate the additional receivers
15397                    // found with what we have do far.  This would be easy,
15398                    // but we also need to de-dup any receivers that are
15399                    // singleUser.
15400                    if (!scannedFirstReceivers) {
15401                        // Collect any single user receivers we had already retrieved.
15402                        scannedFirstReceivers = true;
15403                        for (int i=0; i<receivers.size(); i++) {
15404                            ResolveInfo ri = receivers.get(i);
15405                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15406                                ComponentName cn = new ComponentName(
15407                                        ri.activityInfo.packageName, ri.activityInfo.name);
15408                                if (singleUserReceivers == null) {
15409                                    singleUserReceivers = new HashSet<ComponentName>();
15410                                }
15411                                singleUserReceivers.add(cn);
15412                            }
15413                        }
15414                    }
15415                    // Add the new results to the existing results, tracking
15416                    // and de-dupping single user receivers.
15417                    for (int i=0; i<newReceivers.size(); i++) {
15418                        ResolveInfo ri = newReceivers.get(i);
15419                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15420                            ComponentName cn = new ComponentName(
15421                                    ri.activityInfo.packageName, ri.activityInfo.name);
15422                            if (singleUserReceivers == null) {
15423                                singleUserReceivers = new HashSet<ComponentName>();
15424                            }
15425                            if (!singleUserReceivers.contains(cn)) {
15426                                singleUserReceivers.add(cn);
15427                                receivers.add(ri);
15428                            }
15429                        } else {
15430                            receivers.add(ri);
15431                        }
15432                    }
15433                }
15434            }
15435        } catch (RemoteException ex) {
15436            // pm is in same process, this will never happen.
15437        }
15438        return receivers;
15439    }
15440
15441    private final int broadcastIntentLocked(ProcessRecord callerApp,
15442            String callerPackage, Intent intent, String resolvedType,
15443            IIntentReceiver resultTo, int resultCode, String resultData,
15444            Bundle map, String requiredPermission, int appOp,
15445            boolean ordered, boolean sticky, int callingPid, int callingUid,
15446            int userId) {
15447        intent = new Intent(intent);
15448
15449        // By default broadcasts do not go to stopped apps.
15450        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15451
15452        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15453            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15454            + " ordered=" + ordered + " userid=" + userId);
15455        if ((resultTo != null) && !ordered) {
15456            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15457        }
15458
15459        userId = handleIncomingUser(callingPid, callingUid, userId,
15460                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15461
15462        // Make sure that the user who is receiving this broadcast is started.
15463        // If not, we will just skip it.
15464
15465        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15466            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15467                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15468                Slog.w(TAG, "Skipping broadcast of " + intent
15469                        + ": user " + userId + " is stopped");
15470                return ActivityManager.BROADCAST_SUCCESS;
15471            }
15472        }
15473
15474        /*
15475         * Prevent non-system code (defined here to be non-persistent
15476         * processes) from sending protected broadcasts.
15477         */
15478        int callingAppId = UserHandle.getAppId(callingUid);
15479        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15480            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15481            || callingAppId == Process.NFC_UID || callingUid == 0) {
15482            // Always okay.
15483        } else if (callerApp == null || !callerApp.persistent) {
15484            try {
15485                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15486                        intent.getAction())) {
15487                    String msg = "Permission Denial: not allowed to send broadcast "
15488                            + intent.getAction() + " from pid="
15489                            + callingPid + ", uid=" + callingUid;
15490                    Slog.w(TAG, msg);
15491                    throw new SecurityException(msg);
15492                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15493                    // Special case for compatibility: we don't want apps to send this,
15494                    // but historically it has not been protected and apps may be using it
15495                    // to poke their own app widget.  So, instead of making it protected,
15496                    // just limit it to the caller.
15497                    if (callerApp == null) {
15498                        String msg = "Permission Denial: not allowed to send broadcast "
15499                                + intent.getAction() + " from unknown caller.";
15500                        Slog.w(TAG, msg);
15501                        throw new SecurityException(msg);
15502                    } else if (intent.getComponent() != null) {
15503                        // They are good enough to send to an explicit component...  verify
15504                        // it is being sent to the calling app.
15505                        if (!intent.getComponent().getPackageName().equals(
15506                                callerApp.info.packageName)) {
15507                            String msg = "Permission Denial: not allowed to send broadcast "
15508                                    + intent.getAction() + " to "
15509                                    + intent.getComponent().getPackageName() + " from "
15510                                    + callerApp.info.packageName;
15511                            Slog.w(TAG, msg);
15512                            throw new SecurityException(msg);
15513                        }
15514                    } else {
15515                        // Limit broadcast to their own package.
15516                        intent.setPackage(callerApp.info.packageName);
15517                    }
15518                }
15519            } catch (RemoteException e) {
15520                Slog.w(TAG, "Remote exception", e);
15521                return ActivityManager.BROADCAST_SUCCESS;
15522            }
15523        }
15524
15525        // Handle special intents: if this broadcast is from the package
15526        // manager about a package being removed, we need to remove all of
15527        // its activities from the history stack.
15528        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15529                intent.getAction());
15530        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15531                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15532                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15533                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15534                || uidRemoved) {
15535            if (checkComponentPermission(
15536                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15537                    callingPid, callingUid, -1, true)
15538                    == PackageManager.PERMISSION_GRANTED) {
15539                if (uidRemoved) {
15540                    final Bundle intentExtras = intent.getExtras();
15541                    final int uid = intentExtras != null
15542                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15543                    if (uid >= 0) {
15544                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15545                        synchronized (bs) {
15546                            bs.removeUidStatsLocked(uid);
15547                        }
15548                        mAppOpsService.uidRemoved(uid);
15549                    }
15550                } else {
15551                    // If resources are unavailable just force stop all
15552                    // those packages and flush the attribute cache as well.
15553                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15554                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15555                        if (list != null && (list.length > 0)) {
15556                            for (String pkg : list) {
15557                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15558                                        "storage unmount");
15559                            }
15560                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15561                            sendPackageBroadcastLocked(
15562                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15563                        }
15564                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15565                            intent.getAction())) {
15566                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15567                    } else {
15568                        Uri data = intent.getData();
15569                        String ssp;
15570                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15571                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15572                                    intent.getAction());
15573                            boolean fullUninstall = removed &&
15574                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15575                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15576                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15577                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15578                                        false, fullUninstall, userId,
15579                                        removed ? "pkg removed" : "pkg changed");
15580                            }
15581                            if (removed) {
15582                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15583                                        new String[] {ssp}, userId);
15584                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15585                                    mAppOpsService.packageRemoved(
15586                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15587
15588                                    // Remove all permissions granted from/to this package
15589                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15590                                }
15591                            }
15592                        }
15593                    }
15594                }
15595            } else {
15596                String msg = "Permission Denial: " + intent.getAction()
15597                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15598                        + ", uid=" + callingUid + ")"
15599                        + " requires "
15600                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15601                Slog.w(TAG, msg);
15602                throw new SecurityException(msg);
15603            }
15604
15605        // Special case for adding a package: by default turn on compatibility
15606        // mode.
15607        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15608            Uri data = intent.getData();
15609            String ssp;
15610            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15611                mCompatModePackages.handlePackageAddedLocked(ssp,
15612                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15613            }
15614        }
15615
15616        /*
15617         * If this is the time zone changed action, queue up a message that will reset the timezone
15618         * of all currently running processes. This message will get queued up before the broadcast
15619         * happens.
15620         */
15621        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15622            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15623        }
15624
15625        /*
15626         * If the user set the time, let all running processes know.
15627         */
15628        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15629            final int is24Hour = intent.getBooleanExtra(
15630                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15631            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15632            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15633            synchronized (stats) {
15634                stats.noteCurrentTimeChangedLocked();
15635            }
15636        }
15637
15638        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15639            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15640        }
15641
15642        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15643            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15644            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15645        }
15646
15647        // Add to the sticky list if requested.
15648        if (sticky) {
15649            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15650                    callingPid, callingUid)
15651                    != PackageManager.PERMISSION_GRANTED) {
15652                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15653                        + callingPid + ", uid=" + callingUid
15654                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15655                Slog.w(TAG, msg);
15656                throw new SecurityException(msg);
15657            }
15658            if (requiredPermission != null) {
15659                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15660                        + " and enforce permission " + requiredPermission);
15661                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15662            }
15663            if (intent.getComponent() != null) {
15664                throw new SecurityException(
15665                        "Sticky broadcasts can't target a specific component");
15666            }
15667            // We use userId directly here, since the "all" target is maintained
15668            // as a separate set of sticky broadcasts.
15669            if (userId != UserHandle.USER_ALL) {
15670                // But first, if this is not a broadcast to all users, then
15671                // make sure it doesn't conflict with an existing broadcast to
15672                // all users.
15673                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15674                        UserHandle.USER_ALL);
15675                if (stickies != null) {
15676                    ArrayList<Intent> list = stickies.get(intent.getAction());
15677                    if (list != null) {
15678                        int N = list.size();
15679                        int i;
15680                        for (i=0; i<N; i++) {
15681                            if (intent.filterEquals(list.get(i))) {
15682                                throw new IllegalArgumentException(
15683                                        "Sticky broadcast " + intent + " for user "
15684                                        + userId + " conflicts with existing global broadcast");
15685                            }
15686                        }
15687                    }
15688                }
15689            }
15690            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15691            if (stickies == null) {
15692                stickies = new ArrayMap<String, ArrayList<Intent>>();
15693                mStickyBroadcasts.put(userId, stickies);
15694            }
15695            ArrayList<Intent> list = stickies.get(intent.getAction());
15696            if (list == null) {
15697                list = new ArrayList<Intent>();
15698                stickies.put(intent.getAction(), list);
15699            }
15700            int N = list.size();
15701            int i;
15702            for (i=0; i<N; i++) {
15703                if (intent.filterEquals(list.get(i))) {
15704                    // This sticky already exists, replace it.
15705                    list.set(i, new Intent(intent));
15706                    break;
15707                }
15708            }
15709            if (i >= N) {
15710                list.add(new Intent(intent));
15711            }
15712        }
15713
15714        int[] users;
15715        if (userId == UserHandle.USER_ALL) {
15716            // Caller wants broadcast to go to all started users.
15717            users = mStartedUserArray;
15718        } else {
15719            // Caller wants broadcast to go to one specific user.
15720            users = new int[] {userId};
15721        }
15722
15723        // Figure out who all will receive this broadcast.
15724        List receivers = null;
15725        List<BroadcastFilter> registeredReceivers = null;
15726        // Need to resolve the intent to interested receivers...
15727        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15728                 == 0) {
15729            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15730        }
15731        if (intent.getComponent() == null) {
15732            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15733                // Query one target user at a time, excluding shell-restricted users
15734                UserManagerService ums = getUserManagerLocked();
15735                for (int i = 0; i < users.length; i++) {
15736                    if (ums.hasUserRestriction(
15737                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15738                        continue;
15739                    }
15740                    List<BroadcastFilter> registeredReceiversForUser =
15741                            mReceiverResolver.queryIntent(intent,
15742                                    resolvedType, false, users[i]);
15743                    if (registeredReceivers == null) {
15744                        registeredReceivers = registeredReceiversForUser;
15745                    } else if (registeredReceiversForUser != null) {
15746                        registeredReceivers.addAll(registeredReceiversForUser);
15747                    }
15748                }
15749            } else {
15750                registeredReceivers = mReceiverResolver.queryIntent(intent,
15751                        resolvedType, false, userId);
15752            }
15753        }
15754
15755        final boolean replacePending =
15756                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15757
15758        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15759                + " replacePending=" + replacePending);
15760
15761        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15762        if (!ordered && NR > 0) {
15763            // If we are not serializing this broadcast, then send the
15764            // registered receivers separately so they don't wait for the
15765            // components to be launched.
15766            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15767            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15768                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15769                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15770                    ordered, sticky, false, userId);
15771            if (DEBUG_BROADCAST) Slog.v(
15772                    TAG, "Enqueueing parallel broadcast " + r);
15773            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15774            if (!replaced) {
15775                queue.enqueueParallelBroadcastLocked(r);
15776                queue.scheduleBroadcastsLocked();
15777            }
15778            registeredReceivers = null;
15779            NR = 0;
15780        }
15781
15782        // Merge into one list.
15783        int ir = 0;
15784        if (receivers != null) {
15785            // A special case for PACKAGE_ADDED: do not allow the package
15786            // being added to see this broadcast.  This prevents them from
15787            // using this as a back door to get run as soon as they are
15788            // installed.  Maybe in the future we want to have a special install
15789            // broadcast or such for apps, but we'd like to deliberately make
15790            // this decision.
15791            String skipPackages[] = null;
15792            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15793                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15794                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15795                Uri data = intent.getData();
15796                if (data != null) {
15797                    String pkgName = data.getSchemeSpecificPart();
15798                    if (pkgName != null) {
15799                        skipPackages = new String[] { pkgName };
15800                    }
15801                }
15802            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15803                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15804            }
15805            if (skipPackages != null && (skipPackages.length > 0)) {
15806                for (String skipPackage : skipPackages) {
15807                    if (skipPackage != null) {
15808                        int NT = receivers.size();
15809                        for (int it=0; it<NT; it++) {
15810                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15811                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15812                                receivers.remove(it);
15813                                it--;
15814                                NT--;
15815                            }
15816                        }
15817                    }
15818                }
15819            }
15820
15821            int NT = receivers != null ? receivers.size() : 0;
15822            int it = 0;
15823            ResolveInfo curt = null;
15824            BroadcastFilter curr = null;
15825            while (it < NT && ir < NR) {
15826                if (curt == null) {
15827                    curt = (ResolveInfo)receivers.get(it);
15828                }
15829                if (curr == null) {
15830                    curr = registeredReceivers.get(ir);
15831                }
15832                if (curr.getPriority() >= curt.priority) {
15833                    // Insert this broadcast record into the final list.
15834                    receivers.add(it, curr);
15835                    ir++;
15836                    curr = null;
15837                    it++;
15838                    NT++;
15839                } else {
15840                    // Skip to the next ResolveInfo in the final list.
15841                    it++;
15842                    curt = null;
15843                }
15844            }
15845        }
15846        while (ir < NR) {
15847            if (receivers == null) {
15848                receivers = new ArrayList();
15849            }
15850            receivers.add(registeredReceivers.get(ir));
15851            ir++;
15852        }
15853
15854        if ((receivers != null && receivers.size() > 0)
15855                || resultTo != null) {
15856            BroadcastQueue queue = broadcastQueueForIntent(intent);
15857            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15858                    callerPackage, callingPid, callingUid, resolvedType,
15859                    requiredPermission, appOp, receivers, resultTo, resultCode,
15860                    resultData, map, ordered, sticky, false, userId);
15861            if (DEBUG_BROADCAST) Slog.v(
15862                    TAG, "Enqueueing ordered broadcast " + r
15863                    + ": prev had " + queue.mOrderedBroadcasts.size());
15864            if (DEBUG_BROADCAST) {
15865                int seq = r.intent.getIntExtra("seq", -1);
15866                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15867            }
15868            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15869            if (!replaced) {
15870                queue.enqueueOrderedBroadcastLocked(r);
15871                queue.scheduleBroadcastsLocked();
15872            }
15873        }
15874
15875        return ActivityManager.BROADCAST_SUCCESS;
15876    }
15877
15878    final Intent verifyBroadcastLocked(Intent intent) {
15879        // Refuse possible leaked file descriptors
15880        if (intent != null && intent.hasFileDescriptors() == true) {
15881            throw new IllegalArgumentException("File descriptors passed in Intent");
15882        }
15883
15884        int flags = intent.getFlags();
15885
15886        if (!mProcessesReady) {
15887            // if the caller really truly claims to know what they're doing, go
15888            // ahead and allow the broadcast without launching any receivers
15889            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15890                intent = new Intent(intent);
15891                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15892            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15893                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15894                        + " before boot completion");
15895                throw new IllegalStateException("Cannot broadcast before boot completed");
15896            }
15897        }
15898
15899        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15900            throw new IllegalArgumentException(
15901                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15902        }
15903
15904        return intent;
15905    }
15906
15907    public final int broadcastIntent(IApplicationThread caller,
15908            Intent intent, String resolvedType, IIntentReceiver resultTo,
15909            int resultCode, String resultData, Bundle map,
15910            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15911        enforceNotIsolatedCaller("broadcastIntent");
15912        synchronized(this) {
15913            intent = verifyBroadcastLocked(intent);
15914
15915            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15916            final int callingPid = Binder.getCallingPid();
15917            final int callingUid = Binder.getCallingUid();
15918            final long origId = Binder.clearCallingIdentity();
15919            int res = broadcastIntentLocked(callerApp,
15920                    callerApp != null ? callerApp.info.packageName : null,
15921                    intent, resolvedType, resultTo,
15922                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15923                    callingPid, callingUid, userId);
15924            Binder.restoreCallingIdentity(origId);
15925            return res;
15926        }
15927    }
15928
15929    int broadcastIntentInPackage(String packageName, int uid,
15930            Intent intent, String resolvedType, IIntentReceiver resultTo,
15931            int resultCode, String resultData, Bundle map,
15932            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15933        synchronized(this) {
15934            intent = verifyBroadcastLocked(intent);
15935
15936            final long origId = Binder.clearCallingIdentity();
15937            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15938                    resultTo, resultCode, resultData, map, requiredPermission,
15939                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15940            Binder.restoreCallingIdentity(origId);
15941            return res;
15942        }
15943    }
15944
15945    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15946        // Refuse possible leaked file descriptors
15947        if (intent != null && intent.hasFileDescriptors() == true) {
15948            throw new IllegalArgumentException("File descriptors passed in Intent");
15949        }
15950
15951        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15952                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15953
15954        synchronized(this) {
15955            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15956                    != PackageManager.PERMISSION_GRANTED) {
15957                String msg = "Permission Denial: unbroadcastIntent() from pid="
15958                        + Binder.getCallingPid()
15959                        + ", uid=" + Binder.getCallingUid()
15960                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15961                Slog.w(TAG, msg);
15962                throw new SecurityException(msg);
15963            }
15964            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15965            if (stickies != null) {
15966                ArrayList<Intent> list = stickies.get(intent.getAction());
15967                if (list != null) {
15968                    int N = list.size();
15969                    int i;
15970                    for (i=0; i<N; i++) {
15971                        if (intent.filterEquals(list.get(i))) {
15972                            list.remove(i);
15973                            break;
15974                        }
15975                    }
15976                    if (list.size() <= 0) {
15977                        stickies.remove(intent.getAction());
15978                    }
15979                }
15980                if (stickies.size() <= 0) {
15981                    mStickyBroadcasts.remove(userId);
15982                }
15983            }
15984        }
15985    }
15986
15987    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15988            String resultData, Bundle resultExtras, boolean resultAbort) {
15989        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15990        if (r == null) {
15991            Slog.w(TAG, "finishReceiver called but not found on queue");
15992            return false;
15993        }
15994
15995        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15996    }
15997
15998    void backgroundServicesFinishedLocked(int userId) {
15999        for (BroadcastQueue queue : mBroadcastQueues) {
16000            queue.backgroundServicesFinishedLocked(userId);
16001        }
16002    }
16003
16004    public void finishReceiver(IBinder who, int resultCode, String resultData,
16005            Bundle resultExtras, boolean resultAbort) {
16006        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16007
16008        // Refuse possible leaked file descriptors
16009        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16010            throw new IllegalArgumentException("File descriptors passed in Bundle");
16011        }
16012
16013        final long origId = Binder.clearCallingIdentity();
16014        try {
16015            boolean doNext = false;
16016            BroadcastRecord r;
16017
16018            synchronized(this) {
16019                r = broadcastRecordForReceiverLocked(who);
16020                if (r != null) {
16021                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16022                        resultData, resultExtras, resultAbort, true);
16023                }
16024            }
16025
16026            if (doNext) {
16027                r.queue.processNextBroadcast(false);
16028            }
16029            trimApplications();
16030        } finally {
16031            Binder.restoreCallingIdentity(origId);
16032        }
16033    }
16034
16035    // =========================================================
16036    // INSTRUMENTATION
16037    // =========================================================
16038
16039    public boolean startInstrumentation(ComponentName className,
16040            String profileFile, int flags, Bundle arguments,
16041            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16042            int userId, String abiOverride) {
16043        enforceNotIsolatedCaller("startInstrumentation");
16044        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16045                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16046        // Refuse possible leaked file descriptors
16047        if (arguments != null && arguments.hasFileDescriptors()) {
16048            throw new IllegalArgumentException("File descriptors passed in Bundle");
16049        }
16050
16051        synchronized(this) {
16052            InstrumentationInfo ii = null;
16053            ApplicationInfo ai = null;
16054            try {
16055                ii = mContext.getPackageManager().getInstrumentationInfo(
16056                    className, STOCK_PM_FLAGS);
16057                ai = AppGlobals.getPackageManager().getApplicationInfo(
16058                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16059            } catch (PackageManager.NameNotFoundException e) {
16060            } catch (RemoteException e) {
16061            }
16062            if (ii == null) {
16063                reportStartInstrumentationFailure(watcher, className,
16064                        "Unable to find instrumentation info for: " + className);
16065                return false;
16066            }
16067            if (ai == null) {
16068                reportStartInstrumentationFailure(watcher, className,
16069                        "Unable to find instrumentation target package: " + ii.targetPackage);
16070                return false;
16071            }
16072
16073            int match = mContext.getPackageManager().checkSignatures(
16074                    ii.targetPackage, ii.packageName);
16075            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16076                String msg = "Permission Denial: starting instrumentation "
16077                        + className + " from pid="
16078                        + Binder.getCallingPid()
16079                        + ", uid=" + Binder.getCallingPid()
16080                        + " not allowed because package " + ii.packageName
16081                        + " does not have a signature matching the target "
16082                        + ii.targetPackage;
16083                reportStartInstrumentationFailure(watcher, className, msg);
16084                throw new SecurityException(msg);
16085            }
16086
16087            final long origId = Binder.clearCallingIdentity();
16088            // Instrumentation can kill and relaunch even persistent processes
16089            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16090                    "start instr");
16091            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16092            app.instrumentationClass = className;
16093            app.instrumentationInfo = ai;
16094            app.instrumentationProfileFile = profileFile;
16095            app.instrumentationArguments = arguments;
16096            app.instrumentationWatcher = watcher;
16097            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16098            app.instrumentationResultClass = className;
16099            Binder.restoreCallingIdentity(origId);
16100        }
16101
16102        return true;
16103    }
16104
16105    /**
16106     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16107     * error to the logs, but if somebody is watching, send the report there too.  This enables
16108     * the "am" command to report errors with more information.
16109     *
16110     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16111     * @param cn The component name of the instrumentation.
16112     * @param report The error report.
16113     */
16114    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16115            ComponentName cn, String report) {
16116        Slog.w(TAG, report);
16117        try {
16118            if (watcher != null) {
16119                Bundle results = new Bundle();
16120                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16121                results.putString("Error", report);
16122                watcher.instrumentationStatus(cn, -1, results);
16123            }
16124        } catch (RemoteException e) {
16125            Slog.w(TAG, e);
16126        }
16127    }
16128
16129    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16130        if (app.instrumentationWatcher != null) {
16131            try {
16132                // NOTE:  IInstrumentationWatcher *must* be oneway here
16133                app.instrumentationWatcher.instrumentationFinished(
16134                    app.instrumentationClass,
16135                    resultCode,
16136                    results);
16137            } catch (RemoteException e) {
16138            }
16139        }
16140        if (app.instrumentationUiAutomationConnection != null) {
16141            try {
16142                app.instrumentationUiAutomationConnection.shutdown();
16143            } catch (RemoteException re) {
16144                /* ignore */
16145            }
16146            // Only a UiAutomation can set this flag and now that
16147            // it is finished we make sure it is reset to its default.
16148            mUserIsMonkey = false;
16149        }
16150        app.instrumentationWatcher = null;
16151        app.instrumentationUiAutomationConnection = null;
16152        app.instrumentationClass = null;
16153        app.instrumentationInfo = null;
16154        app.instrumentationProfileFile = null;
16155        app.instrumentationArguments = null;
16156
16157        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16158                "finished inst");
16159    }
16160
16161    public void finishInstrumentation(IApplicationThread target,
16162            int resultCode, Bundle results) {
16163        int userId = UserHandle.getCallingUserId();
16164        // Refuse possible leaked file descriptors
16165        if (results != null && results.hasFileDescriptors()) {
16166            throw new IllegalArgumentException("File descriptors passed in Intent");
16167        }
16168
16169        synchronized(this) {
16170            ProcessRecord app = getRecordForAppLocked(target);
16171            if (app == null) {
16172                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16173                return;
16174            }
16175            final long origId = Binder.clearCallingIdentity();
16176            finishInstrumentationLocked(app, resultCode, results);
16177            Binder.restoreCallingIdentity(origId);
16178        }
16179    }
16180
16181    // =========================================================
16182    // CONFIGURATION
16183    // =========================================================
16184
16185    public ConfigurationInfo getDeviceConfigurationInfo() {
16186        ConfigurationInfo config = new ConfigurationInfo();
16187        synchronized (this) {
16188            config.reqTouchScreen = mConfiguration.touchscreen;
16189            config.reqKeyboardType = mConfiguration.keyboard;
16190            config.reqNavigation = mConfiguration.navigation;
16191            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16192                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16193                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16194            }
16195            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16196                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16197                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16198            }
16199            config.reqGlEsVersion = GL_ES_VERSION;
16200        }
16201        return config;
16202    }
16203
16204    ActivityStack getFocusedStack() {
16205        return mStackSupervisor.getFocusedStack();
16206    }
16207
16208    public Configuration getConfiguration() {
16209        Configuration ci;
16210        synchronized(this) {
16211            ci = new Configuration(mConfiguration);
16212        }
16213        return ci;
16214    }
16215
16216    public void updatePersistentConfiguration(Configuration values) {
16217        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16218                "updateConfiguration()");
16219        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16220                "updateConfiguration()");
16221        if (values == null) {
16222            throw new NullPointerException("Configuration must not be null");
16223        }
16224
16225        synchronized(this) {
16226            final long origId = Binder.clearCallingIdentity();
16227            updateConfigurationLocked(values, null, true, false);
16228            Binder.restoreCallingIdentity(origId);
16229        }
16230    }
16231
16232    public void updateConfiguration(Configuration values) {
16233        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16234                "updateConfiguration()");
16235
16236        synchronized(this) {
16237            if (values == null && mWindowManager != null) {
16238                // sentinel: fetch the current configuration from the window manager
16239                values = mWindowManager.computeNewConfiguration();
16240            }
16241
16242            if (mWindowManager != null) {
16243                mProcessList.applyDisplaySize(mWindowManager);
16244            }
16245
16246            final long origId = Binder.clearCallingIdentity();
16247            if (values != null) {
16248                Settings.System.clearConfiguration(values);
16249            }
16250            updateConfigurationLocked(values, null, false, false);
16251            Binder.restoreCallingIdentity(origId);
16252        }
16253    }
16254
16255    /**
16256     * Do either or both things: (1) change the current configuration, and (2)
16257     * make sure the given activity is running with the (now) current
16258     * configuration.  Returns true if the activity has been left running, or
16259     * false if <var>starting</var> is being destroyed to match the new
16260     * configuration.
16261     * @param persistent TODO
16262     */
16263    boolean updateConfigurationLocked(Configuration values,
16264            ActivityRecord starting, boolean persistent, boolean initLocale) {
16265        int changes = 0;
16266
16267        if (values != null) {
16268            Configuration newConfig = new Configuration(mConfiguration);
16269            changes = newConfig.updateFrom(values);
16270            if (changes != 0) {
16271                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16272                    Slog.i(TAG, "Updating configuration to: " + values);
16273                }
16274
16275                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16276
16277                if (values.locale != null && !initLocale) {
16278                    saveLocaleLocked(values.locale,
16279                                     !values.locale.equals(mConfiguration.locale),
16280                                     values.userSetLocale);
16281                }
16282
16283                mConfigurationSeq++;
16284                if (mConfigurationSeq <= 0) {
16285                    mConfigurationSeq = 1;
16286                }
16287                newConfig.seq = mConfigurationSeq;
16288                mConfiguration = newConfig;
16289                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16290                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16291                //mUsageStatsService.noteStartConfig(newConfig);
16292
16293                final Configuration configCopy = new Configuration(mConfiguration);
16294
16295                // TODO: If our config changes, should we auto dismiss any currently
16296                // showing dialogs?
16297                mShowDialogs = shouldShowDialogs(newConfig);
16298
16299                AttributeCache ac = AttributeCache.instance();
16300                if (ac != null) {
16301                    ac.updateConfiguration(configCopy);
16302                }
16303
16304                // Make sure all resources in our process are updated
16305                // right now, so that anyone who is going to retrieve
16306                // resource values after we return will be sure to get
16307                // the new ones.  This is especially important during
16308                // boot, where the first config change needs to guarantee
16309                // all resources have that config before following boot
16310                // code is executed.
16311                mSystemThread.applyConfigurationToResources(configCopy);
16312
16313                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16314                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16315                    msg.obj = new Configuration(configCopy);
16316                    mHandler.sendMessage(msg);
16317                }
16318
16319                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16320                    ProcessRecord app = mLruProcesses.get(i);
16321                    try {
16322                        if (app.thread != null) {
16323                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16324                                    + app.processName + " new config " + mConfiguration);
16325                            app.thread.scheduleConfigurationChanged(configCopy);
16326                        }
16327                    } catch (Exception e) {
16328                    }
16329                }
16330                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16331                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16332                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16333                        | Intent.FLAG_RECEIVER_FOREGROUND);
16334                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16335                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16336                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16337                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16338                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16339                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16340                    broadcastIntentLocked(null, null, intent,
16341                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16342                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16343                }
16344            }
16345        }
16346
16347        boolean kept = true;
16348        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16349        // mainStack is null during startup.
16350        if (mainStack != null) {
16351            if (changes != 0 && starting == null) {
16352                // If the configuration changed, and the caller is not already
16353                // in the process of starting an activity, then find the top
16354                // activity to check if its configuration needs to change.
16355                starting = mainStack.topRunningActivityLocked(null);
16356            }
16357
16358            if (starting != null) {
16359                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16360                // And we need to make sure at this point that all other activities
16361                // are made visible with the correct configuration.
16362                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16363            }
16364        }
16365
16366        if (values != null && mWindowManager != null) {
16367            mWindowManager.setNewConfiguration(mConfiguration);
16368        }
16369
16370        return kept;
16371    }
16372
16373    /**
16374     * Decide based on the configuration whether we should shouw the ANR,
16375     * crash, etc dialogs.  The idea is that if there is no affordnace to
16376     * press the on-screen buttons, we shouldn't show the dialog.
16377     *
16378     * A thought: SystemUI might also want to get told about this, the Power
16379     * dialog / global actions also might want different behaviors.
16380     */
16381    private static final boolean shouldShowDialogs(Configuration config) {
16382        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16383                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16384    }
16385
16386    /**
16387     * Save the locale.  You must be inside a synchronized (this) block.
16388     */
16389    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16390        if(isDiff) {
16391            SystemProperties.set("user.language", l.getLanguage());
16392            SystemProperties.set("user.region", l.getCountry());
16393        }
16394
16395        if(isPersist) {
16396            SystemProperties.set("persist.sys.language", l.getLanguage());
16397            SystemProperties.set("persist.sys.country", l.getCountry());
16398            SystemProperties.set("persist.sys.localevar", l.getVariant());
16399
16400            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16401        }
16402    }
16403
16404    @Override
16405    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16406        synchronized (this) {
16407            ActivityRecord srec = ActivityRecord.forToken(token);
16408            if (srec.task != null && srec.task.stack != null) {
16409                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16410            }
16411        }
16412        return false;
16413    }
16414
16415    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16416            Intent resultData) {
16417
16418        synchronized (this) {
16419            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16420            if (stack != null) {
16421                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16422            }
16423            return false;
16424        }
16425    }
16426
16427    public int getLaunchedFromUid(IBinder activityToken) {
16428        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16429        if (srec == null) {
16430            return -1;
16431        }
16432        return srec.launchedFromUid;
16433    }
16434
16435    public String getLaunchedFromPackage(IBinder activityToken) {
16436        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16437        if (srec == null) {
16438            return null;
16439        }
16440        return srec.launchedFromPackage;
16441    }
16442
16443    // =========================================================
16444    // LIFETIME MANAGEMENT
16445    // =========================================================
16446
16447    // Returns which broadcast queue the app is the current [or imminent] receiver
16448    // on, or 'null' if the app is not an active broadcast recipient.
16449    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16450        BroadcastRecord r = app.curReceiver;
16451        if (r != null) {
16452            return r.queue;
16453        }
16454
16455        // It's not the current receiver, but it might be starting up to become one
16456        synchronized (this) {
16457            for (BroadcastQueue queue : mBroadcastQueues) {
16458                r = queue.mPendingBroadcast;
16459                if (r != null && r.curApp == app) {
16460                    // found it; report which queue it's in
16461                    return queue;
16462                }
16463            }
16464        }
16465
16466        return null;
16467    }
16468
16469    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16470            boolean doingAll, long now) {
16471        if (mAdjSeq == app.adjSeq) {
16472            // This adjustment has already been computed.
16473            return app.curRawAdj;
16474        }
16475
16476        if (app.thread == null) {
16477            app.adjSeq = mAdjSeq;
16478            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16479            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16480            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16481        }
16482
16483        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16484        app.adjSource = null;
16485        app.adjTarget = null;
16486        app.empty = false;
16487        app.cached = false;
16488
16489        final int activitiesSize = app.activities.size();
16490
16491        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16492            // The max adjustment doesn't allow this app to be anything
16493            // below foreground, so it is not worth doing work for it.
16494            app.adjType = "fixed";
16495            app.adjSeq = mAdjSeq;
16496            app.curRawAdj = app.maxAdj;
16497            app.foregroundActivities = false;
16498            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16499            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16500            // System processes can do UI, and when they do we want to have
16501            // them trim their memory after the user leaves the UI.  To
16502            // facilitate this, here we need to determine whether or not it
16503            // is currently showing UI.
16504            app.systemNoUi = true;
16505            if (app == TOP_APP) {
16506                app.systemNoUi = false;
16507            } else if (activitiesSize > 0) {
16508                for (int j = 0; j < activitiesSize; j++) {
16509                    final ActivityRecord r = app.activities.get(j);
16510                    if (r.visible) {
16511                        app.systemNoUi = false;
16512                    }
16513                }
16514            }
16515            if (!app.systemNoUi) {
16516                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16517            }
16518            return (app.curAdj=app.maxAdj);
16519        }
16520
16521        app.systemNoUi = false;
16522
16523        // Determine the importance of the process, starting with most
16524        // important to least, and assign an appropriate OOM adjustment.
16525        int adj;
16526        int schedGroup;
16527        int procState;
16528        boolean foregroundActivities = false;
16529        BroadcastQueue queue;
16530        if (app == TOP_APP) {
16531            // The last app on the list is the foreground app.
16532            adj = ProcessList.FOREGROUND_APP_ADJ;
16533            schedGroup = Process.THREAD_GROUP_DEFAULT;
16534            app.adjType = "top-activity";
16535            foregroundActivities = true;
16536            procState = ActivityManager.PROCESS_STATE_TOP;
16537        } else if (app.instrumentationClass != null) {
16538            // Don't want to kill running instrumentation.
16539            adj = ProcessList.FOREGROUND_APP_ADJ;
16540            schedGroup = Process.THREAD_GROUP_DEFAULT;
16541            app.adjType = "instrumentation";
16542            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16543        } else if ((queue = isReceivingBroadcast(app)) != null) {
16544            // An app that is currently receiving a broadcast also
16545            // counts as being in the foreground for OOM killer purposes.
16546            // It's placed in a sched group based on the nature of the
16547            // broadcast as reflected by which queue it's active in.
16548            adj = ProcessList.FOREGROUND_APP_ADJ;
16549            schedGroup = (queue == mFgBroadcastQueue)
16550                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16551            app.adjType = "broadcast";
16552            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16553        } else if (app.executingServices.size() > 0) {
16554            // An app that is currently executing a service callback also
16555            // counts as being in the foreground.
16556            adj = ProcessList.FOREGROUND_APP_ADJ;
16557            schedGroup = app.execServicesFg ?
16558                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16559            app.adjType = "exec-service";
16560            procState = ActivityManager.PROCESS_STATE_SERVICE;
16561            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16562        } else {
16563            // As far as we know the process is empty.  We may change our mind later.
16564            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16565            // At this point we don't actually know the adjustment.  Use the cached adj
16566            // value that the caller wants us to.
16567            adj = cachedAdj;
16568            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16569            app.cached = true;
16570            app.empty = true;
16571            app.adjType = "cch-empty";
16572        }
16573
16574        // Examine all activities if not already foreground.
16575        if (!foregroundActivities && activitiesSize > 0) {
16576            for (int j = 0; j < activitiesSize; j++) {
16577                final ActivityRecord r = app.activities.get(j);
16578                if (r.app != app) {
16579                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16580                            + app + "?!?");
16581                    continue;
16582                }
16583                if (r.visible) {
16584                    // App has a visible activity; only upgrade adjustment.
16585                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16586                        adj = ProcessList.VISIBLE_APP_ADJ;
16587                        app.adjType = "visible";
16588                    }
16589                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16590                        procState = ActivityManager.PROCESS_STATE_TOP;
16591                    }
16592                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16593                    app.cached = false;
16594                    app.empty = false;
16595                    foregroundActivities = true;
16596                    break;
16597                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16598                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16599                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16600                        app.adjType = "pausing";
16601                    }
16602                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16603                        procState = ActivityManager.PROCESS_STATE_TOP;
16604                    }
16605                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16606                    app.cached = false;
16607                    app.empty = false;
16608                    foregroundActivities = true;
16609                } else if (r.state == ActivityState.STOPPING) {
16610                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16611                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16612                        app.adjType = "stopping";
16613                    }
16614                    // For the process state, we will at this point consider the
16615                    // process to be cached.  It will be cached either as an activity
16616                    // or empty depending on whether the activity is finishing.  We do
16617                    // this so that we can treat the process as cached for purposes of
16618                    // memory trimming (determing current memory level, trim command to
16619                    // send to process) since there can be an arbitrary number of stopping
16620                    // processes and they should soon all go into the cached state.
16621                    if (!r.finishing) {
16622                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16623                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16624                        }
16625                    }
16626                    app.cached = false;
16627                    app.empty = false;
16628                    foregroundActivities = true;
16629                } else {
16630                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16631                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16632                        app.adjType = "cch-act";
16633                    }
16634                }
16635            }
16636        }
16637
16638        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16639            if (app.foregroundServices) {
16640                // The user is aware of this app, so make it visible.
16641                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16642                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16643                app.cached = false;
16644                app.adjType = "fg-service";
16645                schedGroup = Process.THREAD_GROUP_DEFAULT;
16646            } else if (app.forcingToForeground != null) {
16647                // The user is aware of this app, so make it visible.
16648                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16649                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16650                app.cached = false;
16651                app.adjType = "force-fg";
16652                app.adjSource = app.forcingToForeground;
16653                schedGroup = Process.THREAD_GROUP_DEFAULT;
16654            }
16655        }
16656
16657        if (app == mHeavyWeightProcess) {
16658            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16659                // We don't want to kill the current heavy-weight process.
16660                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16661                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16662                app.cached = false;
16663                app.adjType = "heavy";
16664            }
16665            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16666                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16667            }
16668        }
16669
16670        if (app == mHomeProcess) {
16671            if (adj > ProcessList.HOME_APP_ADJ) {
16672                // This process is hosting what we currently consider to be the
16673                // home app, so we don't want to let it go into the background.
16674                adj = ProcessList.HOME_APP_ADJ;
16675                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16676                app.cached = false;
16677                app.adjType = "home";
16678            }
16679            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16680                procState = ActivityManager.PROCESS_STATE_HOME;
16681            }
16682        }
16683
16684        if (app == mPreviousProcess && app.activities.size() > 0) {
16685            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16686                // This was the previous process that showed UI to the user.
16687                // We want to try to keep it around more aggressively, to give
16688                // a good experience around switching between two apps.
16689                adj = ProcessList.PREVIOUS_APP_ADJ;
16690                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16691                app.cached = false;
16692                app.adjType = "previous";
16693            }
16694            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16695                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16696            }
16697        }
16698
16699        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16700                + " reason=" + app.adjType);
16701
16702        // By default, we use the computed adjustment.  It may be changed if
16703        // there are applications dependent on our services or providers, but
16704        // this gives us a baseline and makes sure we don't get into an
16705        // infinite recursion.
16706        app.adjSeq = mAdjSeq;
16707        app.curRawAdj = adj;
16708        app.hasStartedServices = false;
16709
16710        if (mBackupTarget != null && app == mBackupTarget.app) {
16711            // If possible we want to avoid killing apps while they're being backed up
16712            if (adj > ProcessList.BACKUP_APP_ADJ) {
16713                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16714                adj = ProcessList.BACKUP_APP_ADJ;
16715                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16716                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16717                }
16718                app.adjType = "backup";
16719                app.cached = false;
16720            }
16721            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16722                procState = ActivityManager.PROCESS_STATE_BACKUP;
16723            }
16724        }
16725
16726        boolean mayBeTop = false;
16727
16728        for (int is = app.services.size()-1;
16729                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16730                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16731                        || procState > ActivityManager.PROCESS_STATE_TOP);
16732                is--) {
16733            ServiceRecord s = app.services.valueAt(is);
16734            if (s.startRequested) {
16735                app.hasStartedServices = true;
16736                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16737                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16738                }
16739                if (app.hasShownUi && app != mHomeProcess) {
16740                    // If this process has shown some UI, let it immediately
16741                    // go to the LRU list because it may be pretty heavy with
16742                    // UI stuff.  We'll tag it with a label just to help
16743                    // debug and understand what is going on.
16744                    if (adj > ProcessList.SERVICE_ADJ) {
16745                        app.adjType = "cch-started-ui-services";
16746                    }
16747                } else {
16748                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16749                        // This service has seen some activity within
16750                        // recent memory, so we will keep its process ahead
16751                        // of the background processes.
16752                        if (adj > ProcessList.SERVICE_ADJ) {
16753                            adj = ProcessList.SERVICE_ADJ;
16754                            app.adjType = "started-services";
16755                            app.cached = false;
16756                        }
16757                    }
16758                    // If we have let the service slide into the background
16759                    // state, still have some text describing what it is doing
16760                    // even though the service no longer has an impact.
16761                    if (adj > ProcessList.SERVICE_ADJ) {
16762                        app.adjType = "cch-started-services";
16763                    }
16764                }
16765            }
16766            for (int conni = s.connections.size()-1;
16767                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16768                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16769                            || procState > ActivityManager.PROCESS_STATE_TOP);
16770                    conni--) {
16771                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16772                for (int i = 0;
16773                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16774                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16775                                || procState > ActivityManager.PROCESS_STATE_TOP);
16776                        i++) {
16777                    // XXX should compute this based on the max of
16778                    // all connected clients.
16779                    ConnectionRecord cr = clist.get(i);
16780                    if (cr.binding.client == app) {
16781                        // Binding to ourself is not interesting.
16782                        continue;
16783                    }
16784                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16785                        ProcessRecord client = cr.binding.client;
16786                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16787                                TOP_APP, doingAll, now);
16788                        int clientProcState = client.curProcState;
16789                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16790                            // If the other app is cached for any reason, for purposes here
16791                            // we are going to consider it empty.  The specific cached state
16792                            // doesn't propagate except under certain conditions.
16793                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16794                        }
16795                        String adjType = null;
16796                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16797                            // Not doing bind OOM management, so treat
16798                            // this guy more like a started service.
16799                            if (app.hasShownUi && app != mHomeProcess) {
16800                                // If this process has shown some UI, let it immediately
16801                                // go to the LRU list because it may be pretty heavy with
16802                                // UI stuff.  We'll tag it with a label just to help
16803                                // debug and understand what is going on.
16804                                if (adj > clientAdj) {
16805                                    adjType = "cch-bound-ui-services";
16806                                }
16807                                app.cached = false;
16808                                clientAdj = adj;
16809                                clientProcState = procState;
16810                            } else {
16811                                if (now >= (s.lastActivity
16812                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16813                                    // This service has not seen activity within
16814                                    // recent memory, so allow it to drop to the
16815                                    // LRU list if there is no other reason to keep
16816                                    // it around.  We'll also tag it with a label just
16817                                    // to help debug and undertand what is going on.
16818                                    if (adj > clientAdj) {
16819                                        adjType = "cch-bound-services";
16820                                    }
16821                                    clientAdj = adj;
16822                                }
16823                            }
16824                        }
16825                        if (adj > clientAdj) {
16826                            // If this process has recently shown UI, and
16827                            // the process that is binding to it is less
16828                            // important than being visible, then we don't
16829                            // care about the binding as much as we care
16830                            // about letting this process get into the LRU
16831                            // list to be killed and restarted if needed for
16832                            // memory.
16833                            if (app.hasShownUi && app != mHomeProcess
16834                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16835                                adjType = "cch-bound-ui-services";
16836                            } else {
16837                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16838                                        |Context.BIND_IMPORTANT)) != 0) {
16839                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16840                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16841                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16842                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16843                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16844                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16845                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16846                                    adj = clientAdj;
16847                                } else {
16848                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16849                                        adj = ProcessList.VISIBLE_APP_ADJ;
16850                                    }
16851                                }
16852                                if (!client.cached) {
16853                                    app.cached = false;
16854                                }
16855                                adjType = "service";
16856                            }
16857                        }
16858                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16859                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16860                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16861                            }
16862                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16863                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16864                                    // Special handling of clients who are in the top state.
16865                                    // We *may* want to consider this process to be in the
16866                                    // top state as well, but only if there is not another
16867                                    // reason for it to be running.  Being on the top is a
16868                                    // special state, meaning you are specifically running
16869                                    // for the current top app.  If the process is already
16870                                    // running in the background for some other reason, it
16871                                    // is more important to continue considering it to be
16872                                    // in the background state.
16873                                    mayBeTop = true;
16874                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16875                                } else {
16876                                    // Special handling for above-top states (persistent
16877                                    // processes).  These should not bring the current process
16878                                    // into the top state, since they are not on top.  Instead
16879                                    // give them the best state after that.
16880                                    clientProcState =
16881                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16882                                }
16883                            }
16884                        } else {
16885                            if (clientProcState <
16886                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16887                                clientProcState =
16888                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16889                            }
16890                        }
16891                        if (procState > clientProcState) {
16892                            procState = clientProcState;
16893                        }
16894                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16895                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16896                            app.pendingUiClean = true;
16897                        }
16898                        if (adjType != null) {
16899                            app.adjType = adjType;
16900                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16901                                    .REASON_SERVICE_IN_USE;
16902                            app.adjSource = cr.binding.client;
16903                            app.adjSourceProcState = clientProcState;
16904                            app.adjTarget = s.name;
16905                        }
16906                    }
16907                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16908                        app.treatLikeActivity = true;
16909                    }
16910                    final ActivityRecord a = cr.activity;
16911                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16912                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16913                                (a.visible || a.state == ActivityState.RESUMED
16914                                 || a.state == ActivityState.PAUSING)) {
16915                            adj = ProcessList.FOREGROUND_APP_ADJ;
16916                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16917                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16918                            }
16919                            app.cached = false;
16920                            app.adjType = "service";
16921                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16922                                    .REASON_SERVICE_IN_USE;
16923                            app.adjSource = a;
16924                            app.adjSourceProcState = procState;
16925                            app.adjTarget = s.name;
16926                        }
16927                    }
16928                }
16929            }
16930        }
16931
16932        for (int provi = app.pubProviders.size()-1;
16933                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16934                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16935                        || procState > ActivityManager.PROCESS_STATE_TOP);
16936                provi--) {
16937            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16938            for (int i = cpr.connections.size()-1;
16939                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16940                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16941                            || procState > ActivityManager.PROCESS_STATE_TOP);
16942                    i--) {
16943                ContentProviderConnection conn = cpr.connections.get(i);
16944                ProcessRecord client = conn.client;
16945                if (client == app) {
16946                    // Being our own client is not interesting.
16947                    continue;
16948                }
16949                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16950                int clientProcState = client.curProcState;
16951                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16952                    // If the other app is cached for any reason, for purposes here
16953                    // we are going to consider it empty.
16954                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16955                }
16956                if (adj > clientAdj) {
16957                    if (app.hasShownUi && app != mHomeProcess
16958                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16959                        app.adjType = "cch-ui-provider";
16960                    } else {
16961                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16962                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16963                        app.adjType = "provider";
16964                    }
16965                    app.cached &= client.cached;
16966                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16967                            .REASON_PROVIDER_IN_USE;
16968                    app.adjSource = client;
16969                    app.adjSourceProcState = clientProcState;
16970                    app.adjTarget = cpr.name;
16971                }
16972                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16973                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16974                        // Special handling of clients who are in the top state.
16975                        // We *may* want to consider this process to be in the
16976                        // top state as well, but only if there is not another
16977                        // reason for it to be running.  Being on the top is a
16978                        // special state, meaning you are specifically running
16979                        // for the current top app.  If the process is already
16980                        // running in the background for some other reason, it
16981                        // is more important to continue considering it to be
16982                        // in the background state.
16983                        mayBeTop = true;
16984                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16985                    } else {
16986                        // Special handling for above-top states (persistent
16987                        // processes).  These should not bring the current process
16988                        // into the top state, since they are not on top.  Instead
16989                        // give them the best state after that.
16990                        clientProcState =
16991                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16992                    }
16993                }
16994                if (procState > clientProcState) {
16995                    procState = clientProcState;
16996                }
16997                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16998                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16999                }
17000            }
17001            // If the provider has external (non-framework) process
17002            // dependencies, ensure that its adjustment is at least
17003            // FOREGROUND_APP_ADJ.
17004            if (cpr.hasExternalProcessHandles()) {
17005                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17006                    adj = ProcessList.FOREGROUND_APP_ADJ;
17007                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17008                    app.cached = false;
17009                    app.adjType = "provider";
17010                    app.adjTarget = cpr.name;
17011                }
17012                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17013                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17014                }
17015            }
17016        }
17017
17018        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17019            // A client of one of our services or providers is in the top state.  We
17020            // *may* want to be in the top state, but not if we are already running in
17021            // the background for some other reason.  For the decision here, we are going
17022            // to pick out a few specific states that we want to remain in when a client
17023            // is top (states that tend to be longer-term) and otherwise allow it to go
17024            // to the top state.
17025            switch (procState) {
17026                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17027                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17028                case ActivityManager.PROCESS_STATE_SERVICE:
17029                    // These all are longer-term states, so pull them up to the top
17030                    // of the background states, but not all the way to the top state.
17031                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17032                    break;
17033                default:
17034                    // Otherwise, top is a better choice, so take it.
17035                    procState = ActivityManager.PROCESS_STATE_TOP;
17036                    break;
17037            }
17038        }
17039
17040        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17041            if (app.hasClientActivities) {
17042                // This is a cached process, but with client activities.  Mark it so.
17043                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17044                app.adjType = "cch-client-act";
17045            } else if (app.treatLikeActivity) {
17046                // This is a cached process, but somebody wants us to treat it like it has
17047                // an activity, okay!
17048                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17049                app.adjType = "cch-as-act";
17050            }
17051        }
17052
17053        if (adj == ProcessList.SERVICE_ADJ) {
17054            if (doingAll) {
17055                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17056                mNewNumServiceProcs++;
17057                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17058                if (!app.serviceb) {
17059                    // This service isn't far enough down on the LRU list to
17060                    // normally be a B service, but if we are low on RAM and it
17061                    // is large we want to force it down since we would prefer to
17062                    // keep launcher over it.
17063                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17064                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17065                        app.serviceHighRam = true;
17066                        app.serviceb = true;
17067                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17068                    } else {
17069                        mNewNumAServiceProcs++;
17070                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17071                    }
17072                } else {
17073                    app.serviceHighRam = false;
17074                }
17075            }
17076            if (app.serviceb) {
17077                adj = ProcessList.SERVICE_B_ADJ;
17078            }
17079        }
17080
17081        app.curRawAdj = adj;
17082
17083        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17084        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17085        if (adj > app.maxAdj) {
17086            adj = app.maxAdj;
17087            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17088                schedGroup = Process.THREAD_GROUP_DEFAULT;
17089            }
17090        }
17091
17092        // Do final modification to adj.  Everything we do between here and applying
17093        // the final setAdj must be done in this function, because we will also use
17094        // it when computing the final cached adj later.  Note that we don't need to
17095        // worry about this for max adj above, since max adj will always be used to
17096        // keep it out of the cached vaues.
17097        app.curAdj = app.modifyRawOomAdj(adj);
17098        app.curSchedGroup = schedGroup;
17099        app.curProcState = procState;
17100        app.foregroundActivities = foregroundActivities;
17101
17102        return app.curRawAdj;
17103    }
17104
17105    /**
17106     * Schedule PSS collection of a process.
17107     */
17108    void requestPssLocked(ProcessRecord proc, int procState) {
17109        if (mPendingPssProcesses.contains(proc)) {
17110            return;
17111        }
17112        if (mPendingPssProcesses.size() == 0) {
17113            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17114        }
17115        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17116        proc.pssProcState = procState;
17117        mPendingPssProcesses.add(proc);
17118    }
17119
17120    /**
17121     * Schedule PSS collection of all processes.
17122     */
17123    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17124        if (!always) {
17125            if (now < (mLastFullPssTime +
17126                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17127                return;
17128            }
17129        }
17130        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17131        mLastFullPssTime = now;
17132        mFullPssPending = true;
17133        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17134        mPendingPssProcesses.clear();
17135        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17136            ProcessRecord app = mLruProcesses.get(i);
17137            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17138                app.pssProcState = app.setProcState;
17139                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17140                        isSleeping(), now);
17141                mPendingPssProcesses.add(app);
17142            }
17143        }
17144        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17145    }
17146
17147    /**
17148     * Ask a given process to GC right now.
17149     */
17150    final void performAppGcLocked(ProcessRecord app) {
17151        try {
17152            app.lastRequestedGc = SystemClock.uptimeMillis();
17153            if (app.thread != null) {
17154                if (app.reportLowMemory) {
17155                    app.reportLowMemory = false;
17156                    app.thread.scheduleLowMemory();
17157                } else {
17158                    app.thread.processInBackground();
17159                }
17160            }
17161        } catch (Exception e) {
17162            // whatever.
17163        }
17164    }
17165
17166    /**
17167     * Returns true if things are idle enough to perform GCs.
17168     */
17169    private final boolean canGcNowLocked() {
17170        boolean processingBroadcasts = false;
17171        for (BroadcastQueue q : mBroadcastQueues) {
17172            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17173                processingBroadcasts = true;
17174            }
17175        }
17176        return !processingBroadcasts
17177                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17178    }
17179
17180    /**
17181     * Perform GCs on all processes that are waiting for it, but only
17182     * if things are idle.
17183     */
17184    final void performAppGcsLocked() {
17185        final int N = mProcessesToGc.size();
17186        if (N <= 0) {
17187            return;
17188        }
17189        if (canGcNowLocked()) {
17190            while (mProcessesToGc.size() > 0) {
17191                ProcessRecord proc = mProcessesToGc.remove(0);
17192                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17193                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17194                            <= SystemClock.uptimeMillis()) {
17195                        // To avoid spamming the system, we will GC processes one
17196                        // at a time, waiting a few seconds between each.
17197                        performAppGcLocked(proc);
17198                        scheduleAppGcsLocked();
17199                        return;
17200                    } else {
17201                        // It hasn't been long enough since we last GCed this
17202                        // process...  put it in the list to wait for its time.
17203                        addProcessToGcListLocked(proc);
17204                        break;
17205                    }
17206                }
17207            }
17208
17209            scheduleAppGcsLocked();
17210        }
17211    }
17212
17213    /**
17214     * If all looks good, perform GCs on all processes waiting for them.
17215     */
17216    final void performAppGcsIfAppropriateLocked() {
17217        if (canGcNowLocked()) {
17218            performAppGcsLocked();
17219            return;
17220        }
17221        // Still not idle, wait some more.
17222        scheduleAppGcsLocked();
17223    }
17224
17225    /**
17226     * Schedule the execution of all pending app GCs.
17227     */
17228    final void scheduleAppGcsLocked() {
17229        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17230
17231        if (mProcessesToGc.size() > 0) {
17232            // Schedule a GC for the time to the next process.
17233            ProcessRecord proc = mProcessesToGc.get(0);
17234            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17235
17236            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17237            long now = SystemClock.uptimeMillis();
17238            if (when < (now+GC_TIMEOUT)) {
17239                when = now + GC_TIMEOUT;
17240            }
17241            mHandler.sendMessageAtTime(msg, when);
17242        }
17243    }
17244
17245    /**
17246     * Add a process to the array of processes waiting to be GCed.  Keeps the
17247     * list in sorted order by the last GC time.  The process can't already be
17248     * on the list.
17249     */
17250    final void addProcessToGcListLocked(ProcessRecord proc) {
17251        boolean added = false;
17252        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17253            if (mProcessesToGc.get(i).lastRequestedGc <
17254                    proc.lastRequestedGc) {
17255                added = true;
17256                mProcessesToGc.add(i+1, proc);
17257                break;
17258            }
17259        }
17260        if (!added) {
17261            mProcessesToGc.add(0, proc);
17262        }
17263    }
17264
17265    /**
17266     * Set up to ask a process to GC itself.  This will either do it
17267     * immediately, or put it on the list of processes to gc the next
17268     * time things are idle.
17269     */
17270    final void scheduleAppGcLocked(ProcessRecord app) {
17271        long now = SystemClock.uptimeMillis();
17272        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17273            return;
17274        }
17275        if (!mProcessesToGc.contains(app)) {
17276            addProcessToGcListLocked(app);
17277            scheduleAppGcsLocked();
17278        }
17279    }
17280
17281    final void checkExcessivePowerUsageLocked(boolean doKills) {
17282        updateCpuStatsNow();
17283
17284        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17285        boolean doWakeKills = doKills;
17286        boolean doCpuKills = doKills;
17287        if (mLastPowerCheckRealtime == 0) {
17288            doWakeKills = false;
17289        }
17290        if (mLastPowerCheckUptime == 0) {
17291            doCpuKills = false;
17292        }
17293        if (stats.isScreenOn()) {
17294            doWakeKills = false;
17295        }
17296        final long curRealtime = SystemClock.elapsedRealtime();
17297        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17298        final long curUptime = SystemClock.uptimeMillis();
17299        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17300        mLastPowerCheckRealtime = curRealtime;
17301        mLastPowerCheckUptime = curUptime;
17302        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17303            doWakeKills = false;
17304        }
17305        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17306            doCpuKills = false;
17307        }
17308        int i = mLruProcesses.size();
17309        while (i > 0) {
17310            i--;
17311            ProcessRecord app = mLruProcesses.get(i);
17312            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17313                long wtime;
17314                synchronized (stats) {
17315                    wtime = stats.getProcessWakeTime(app.info.uid,
17316                            app.pid, curRealtime);
17317                }
17318                long wtimeUsed = wtime - app.lastWakeTime;
17319                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17320                if (DEBUG_POWER) {
17321                    StringBuilder sb = new StringBuilder(128);
17322                    sb.append("Wake for ");
17323                    app.toShortString(sb);
17324                    sb.append(": over ");
17325                    TimeUtils.formatDuration(realtimeSince, sb);
17326                    sb.append(" used ");
17327                    TimeUtils.formatDuration(wtimeUsed, sb);
17328                    sb.append(" (");
17329                    sb.append((wtimeUsed*100)/realtimeSince);
17330                    sb.append("%)");
17331                    Slog.i(TAG, sb.toString());
17332                    sb.setLength(0);
17333                    sb.append("CPU for ");
17334                    app.toShortString(sb);
17335                    sb.append(": over ");
17336                    TimeUtils.formatDuration(uptimeSince, sb);
17337                    sb.append(" used ");
17338                    TimeUtils.formatDuration(cputimeUsed, sb);
17339                    sb.append(" (");
17340                    sb.append((cputimeUsed*100)/uptimeSince);
17341                    sb.append("%)");
17342                    Slog.i(TAG, sb.toString());
17343                }
17344                // If a process has held a wake lock for more
17345                // than 50% of the time during this period,
17346                // that sounds bad.  Kill!
17347                if (doWakeKills && realtimeSince > 0
17348                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17349                    synchronized (stats) {
17350                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17351                                realtimeSince, wtimeUsed);
17352                    }
17353                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17354                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17355                } else if (doCpuKills && uptimeSince > 0
17356                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17357                    synchronized (stats) {
17358                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17359                                uptimeSince, cputimeUsed);
17360                    }
17361                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17362                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17363                } else {
17364                    app.lastWakeTime = wtime;
17365                    app.lastCpuTime = app.curCpuTime;
17366                }
17367            }
17368        }
17369    }
17370
17371    private final boolean applyOomAdjLocked(ProcessRecord app,
17372            ProcessRecord TOP_APP, boolean doingAll, long now) {
17373        boolean success = true;
17374
17375        if (app.curRawAdj != app.setRawAdj) {
17376            app.setRawAdj = app.curRawAdj;
17377        }
17378
17379        int changes = 0;
17380
17381        if (app.curAdj != app.setAdj) {
17382            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17383            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17384                TAG, "Set " + app.pid + " " + app.processName +
17385                " adj " + app.curAdj + ": " + app.adjType);
17386            app.setAdj = app.curAdj;
17387        }
17388
17389        if (app.setSchedGroup != app.curSchedGroup) {
17390            app.setSchedGroup = app.curSchedGroup;
17391            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17392                    "Setting process group of " + app.processName
17393                    + " to " + app.curSchedGroup);
17394            if (app.waitingToKill != null &&
17395                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17396                app.kill(app.waitingToKill, true);
17397                success = false;
17398            } else {
17399                if (true) {
17400                    long oldId = Binder.clearCallingIdentity();
17401                    try {
17402                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17403                    } catch (Exception e) {
17404                        Slog.w(TAG, "Failed setting process group of " + app.pid
17405                                + " to " + app.curSchedGroup);
17406                        e.printStackTrace();
17407                    } finally {
17408                        Binder.restoreCallingIdentity(oldId);
17409                    }
17410                } else {
17411                    if (app.thread != null) {
17412                        try {
17413                            app.thread.setSchedulingGroup(app.curSchedGroup);
17414                        } catch (RemoteException e) {
17415                        }
17416                    }
17417                }
17418                Process.setSwappiness(app.pid,
17419                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17420            }
17421        }
17422        if (app.repForegroundActivities != app.foregroundActivities) {
17423            app.repForegroundActivities = app.foregroundActivities;
17424            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17425        }
17426        if (app.repProcState != app.curProcState) {
17427            app.repProcState = app.curProcState;
17428            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17429            if (app.thread != null) {
17430                try {
17431                    if (false) {
17432                        //RuntimeException h = new RuntimeException("here");
17433                        Slog.i(TAG, "Sending new process state " + app.repProcState
17434                                + " to " + app /*, h*/);
17435                    }
17436                    app.thread.setProcessState(app.repProcState);
17437                } catch (RemoteException e) {
17438                }
17439            }
17440        }
17441        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17442                app.setProcState)) {
17443            app.lastStateTime = now;
17444            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17445                    isSleeping(), now);
17446            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17447                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17448                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17449                    + (app.nextPssTime-now) + ": " + app);
17450        } else {
17451            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17452                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17453                requestPssLocked(app, app.setProcState);
17454                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17455                        isSleeping(), now);
17456            } else if (false && DEBUG_PSS) {
17457                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17458            }
17459        }
17460        if (app.setProcState != app.curProcState) {
17461            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17462                    "Proc state change of " + app.processName
17463                    + " to " + app.curProcState);
17464            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17465            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17466            if (setImportant && !curImportant) {
17467                // This app is no longer something we consider important enough to allow to
17468                // use arbitrary amounts of battery power.  Note
17469                // its current wake lock time to later know to kill it if
17470                // it is not behaving well.
17471                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17472                synchronized (stats) {
17473                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17474                            app.pid, SystemClock.elapsedRealtime());
17475                }
17476                app.lastCpuTime = app.curCpuTime;
17477
17478            }
17479            app.setProcState = app.curProcState;
17480            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17481                app.notCachedSinceIdle = false;
17482            }
17483            if (!doingAll) {
17484                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17485            } else {
17486                app.procStateChanged = true;
17487            }
17488        }
17489
17490        if (changes != 0) {
17491            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17492            int i = mPendingProcessChanges.size()-1;
17493            ProcessChangeItem item = null;
17494            while (i >= 0) {
17495                item = mPendingProcessChanges.get(i);
17496                if (item.pid == app.pid) {
17497                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17498                    break;
17499                }
17500                i--;
17501            }
17502            if (i < 0) {
17503                // No existing item in pending changes; need a new one.
17504                final int NA = mAvailProcessChanges.size();
17505                if (NA > 0) {
17506                    item = mAvailProcessChanges.remove(NA-1);
17507                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17508                } else {
17509                    item = new ProcessChangeItem();
17510                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17511                }
17512                item.changes = 0;
17513                item.pid = app.pid;
17514                item.uid = app.info.uid;
17515                if (mPendingProcessChanges.size() == 0) {
17516                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17517                            "*** Enqueueing dispatch processes changed!");
17518                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17519                }
17520                mPendingProcessChanges.add(item);
17521            }
17522            item.changes |= changes;
17523            item.processState = app.repProcState;
17524            item.foregroundActivities = app.repForegroundActivities;
17525            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17526                    + Integer.toHexString(System.identityHashCode(item))
17527                    + " " + app.toShortString() + ": changes=" + item.changes
17528                    + " procState=" + item.processState
17529                    + " foreground=" + item.foregroundActivities
17530                    + " type=" + app.adjType + " source=" + app.adjSource
17531                    + " target=" + app.adjTarget);
17532        }
17533
17534        return success;
17535    }
17536
17537    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17538        if (proc.thread != null) {
17539            if (proc.baseProcessTracker != null) {
17540                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17541            }
17542            if (proc.repProcState >= 0) {
17543                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17544                        proc.repProcState);
17545            }
17546        }
17547    }
17548
17549    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17550            ProcessRecord TOP_APP, boolean doingAll, long now) {
17551        if (app.thread == null) {
17552            return false;
17553        }
17554
17555        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17556
17557        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17558    }
17559
17560    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17561            boolean oomAdj) {
17562        if (isForeground != proc.foregroundServices) {
17563            proc.foregroundServices = isForeground;
17564            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17565                    proc.info.uid);
17566            if (isForeground) {
17567                if (curProcs == null) {
17568                    curProcs = new ArrayList<ProcessRecord>();
17569                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17570                }
17571                if (!curProcs.contains(proc)) {
17572                    curProcs.add(proc);
17573                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17574                            proc.info.packageName, proc.info.uid);
17575                }
17576            } else {
17577                if (curProcs != null) {
17578                    if (curProcs.remove(proc)) {
17579                        mBatteryStatsService.noteEvent(
17580                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17581                                proc.info.packageName, proc.info.uid);
17582                        if (curProcs.size() <= 0) {
17583                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17584                        }
17585                    }
17586                }
17587            }
17588            if (oomAdj) {
17589                updateOomAdjLocked();
17590            }
17591        }
17592    }
17593
17594    private final ActivityRecord resumedAppLocked() {
17595        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17596        String pkg;
17597        int uid;
17598        if (act != null) {
17599            pkg = act.packageName;
17600            uid = act.info.applicationInfo.uid;
17601        } else {
17602            pkg = null;
17603            uid = -1;
17604        }
17605        // Has the UID or resumed package name changed?
17606        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17607                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17608            if (mCurResumedPackage != null) {
17609                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17610                        mCurResumedPackage, mCurResumedUid);
17611            }
17612            mCurResumedPackage = pkg;
17613            mCurResumedUid = uid;
17614            if (mCurResumedPackage != null) {
17615                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17616                        mCurResumedPackage, mCurResumedUid);
17617            }
17618        }
17619        return act;
17620    }
17621
17622    final boolean updateOomAdjLocked(ProcessRecord app) {
17623        final ActivityRecord TOP_ACT = resumedAppLocked();
17624        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17625        final boolean wasCached = app.cached;
17626
17627        mAdjSeq++;
17628
17629        // This is the desired cached adjusment we want to tell it to use.
17630        // If our app is currently cached, we know it, and that is it.  Otherwise,
17631        // we don't know it yet, and it needs to now be cached we will then
17632        // need to do a complete oom adj.
17633        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17634                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17635        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17636                SystemClock.uptimeMillis());
17637        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17638            // Changed to/from cached state, so apps after it in the LRU
17639            // list may also be changed.
17640            updateOomAdjLocked();
17641        }
17642        return success;
17643    }
17644
17645    final void updateOomAdjLocked() {
17646        final ActivityRecord TOP_ACT = resumedAppLocked();
17647        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17648        final long now = SystemClock.uptimeMillis();
17649        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17650        final int N = mLruProcesses.size();
17651
17652        if (false) {
17653            RuntimeException e = new RuntimeException();
17654            e.fillInStackTrace();
17655            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17656        }
17657
17658        mAdjSeq++;
17659        mNewNumServiceProcs = 0;
17660        mNewNumAServiceProcs = 0;
17661
17662        final int emptyProcessLimit;
17663        final int cachedProcessLimit;
17664        if (mProcessLimit <= 0) {
17665            emptyProcessLimit = cachedProcessLimit = 0;
17666        } else if (mProcessLimit == 1) {
17667            emptyProcessLimit = 1;
17668            cachedProcessLimit = 0;
17669        } else {
17670            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17671            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17672        }
17673
17674        // Let's determine how many processes we have running vs.
17675        // how many slots we have for background processes; we may want
17676        // to put multiple processes in a slot of there are enough of
17677        // them.
17678        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17679                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17680        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17681        if (numEmptyProcs > cachedProcessLimit) {
17682            // If there are more empty processes than our limit on cached
17683            // processes, then use the cached process limit for the factor.
17684            // This ensures that the really old empty processes get pushed
17685            // down to the bottom, so if we are running low on memory we will
17686            // have a better chance at keeping around more cached processes
17687            // instead of a gazillion empty processes.
17688            numEmptyProcs = cachedProcessLimit;
17689        }
17690        int emptyFactor = numEmptyProcs/numSlots;
17691        if (emptyFactor < 1) emptyFactor = 1;
17692        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17693        if (cachedFactor < 1) cachedFactor = 1;
17694        int stepCached = 0;
17695        int stepEmpty = 0;
17696        int numCached = 0;
17697        int numEmpty = 0;
17698        int numTrimming = 0;
17699
17700        mNumNonCachedProcs = 0;
17701        mNumCachedHiddenProcs = 0;
17702
17703        // First update the OOM adjustment for each of the
17704        // application processes based on their current state.
17705        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17706        int nextCachedAdj = curCachedAdj+1;
17707        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17708        int nextEmptyAdj = curEmptyAdj+2;
17709        for (int i=N-1; i>=0; i--) {
17710            ProcessRecord app = mLruProcesses.get(i);
17711            if (!app.killedByAm && app.thread != null) {
17712                app.procStateChanged = false;
17713                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17714
17715                // If we haven't yet assigned the final cached adj
17716                // to the process, do that now.
17717                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17718                    switch (app.curProcState) {
17719                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17720                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17721                            // This process is a cached process holding activities...
17722                            // assign it the next cached value for that type, and then
17723                            // step that cached level.
17724                            app.curRawAdj = curCachedAdj;
17725                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17726                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17727                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17728                                    + ")");
17729                            if (curCachedAdj != nextCachedAdj) {
17730                                stepCached++;
17731                                if (stepCached >= cachedFactor) {
17732                                    stepCached = 0;
17733                                    curCachedAdj = nextCachedAdj;
17734                                    nextCachedAdj += 2;
17735                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17736                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17737                                    }
17738                                }
17739                            }
17740                            break;
17741                        default:
17742                            // For everything else, assign next empty cached process
17743                            // level and bump that up.  Note that this means that
17744                            // long-running services that have dropped down to the
17745                            // cached level will be treated as empty (since their process
17746                            // state is still as a service), which is what we want.
17747                            app.curRawAdj = curEmptyAdj;
17748                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17749                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17750                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17751                                    + ")");
17752                            if (curEmptyAdj != nextEmptyAdj) {
17753                                stepEmpty++;
17754                                if (stepEmpty >= emptyFactor) {
17755                                    stepEmpty = 0;
17756                                    curEmptyAdj = nextEmptyAdj;
17757                                    nextEmptyAdj += 2;
17758                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17759                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17760                                    }
17761                                }
17762                            }
17763                            break;
17764                    }
17765                }
17766
17767                applyOomAdjLocked(app, TOP_APP, true, now);
17768
17769                // Count the number of process types.
17770                switch (app.curProcState) {
17771                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17772                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17773                        mNumCachedHiddenProcs++;
17774                        numCached++;
17775                        if (numCached > cachedProcessLimit) {
17776                            app.kill("cached #" + numCached, true);
17777                        }
17778                        break;
17779                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17780                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17781                                && app.lastActivityTime < oldTime) {
17782                            app.kill("empty for "
17783                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17784                                    / 1000) + "s", true);
17785                        } else {
17786                            numEmpty++;
17787                            if (numEmpty > emptyProcessLimit) {
17788                                app.kill("empty #" + numEmpty, true);
17789                            }
17790                        }
17791                        break;
17792                    default:
17793                        mNumNonCachedProcs++;
17794                        break;
17795                }
17796
17797                if (app.isolated && app.services.size() <= 0) {
17798                    // If this is an isolated process, and there are no
17799                    // services running in it, then the process is no longer
17800                    // needed.  We agressively kill these because we can by
17801                    // definition not re-use the same process again, and it is
17802                    // good to avoid having whatever code was running in them
17803                    // left sitting around after no longer needed.
17804                    app.kill("isolated not needed", true);
17805                }
17806
17807                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17808                        && !app.killedByAm) {
17809                    numTrimming++;
17810                }
17811            }
17812        }
17813
17814        mNumServiceProcs = mNewNumServiceProcs;
17815
17816        // Now determine the memory trimming level of background processes.
17817        // Unfortunately we need to start at the back of the list to do this
17818        // properly.  We only do this if the number of background apps we
17819        // are managing to keep around is less than half the maximum we desire;
17820        // if we are keeping a good number around, we'll let them use whatever
17821        // memory they want.
17822        final int numCachedAndEmpty = numCached + numEmpty;
17823        int memFactor;
17824        if (numCached <= ProcessList.TRIM_CACHED_APPS
17825                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17826            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17827                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17828            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17829                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17830            } else {
17831                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17832            }
17833        } else {
17834            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17835        }
17836        // We always allow the memory level to go up (better).  We only allow it to go
17837        // down if we are in a state where that is allowed, *and* the total number of processes
17838        // has gone down since last time.
17839        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17840                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17841                + " last=" + mLastNumProcesses);
17842        if (memFactor > mLastMemoryLevel) {
17843            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17844                memFactor = mLastMemoryLevel;
17845                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17846            }
17847        }
17848        mLastMemoryLevel = memFactor;
17849        mLastNumProcesses = mLruProcesses.size();
17850        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17851        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17852        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17853            if (mLowRamStartTime == 0) {
17854                mLowRamStartTime = now;
17855            }
17856            int step = 0;
17857            int fgTrimLevel;
17858            switch (memFactor) {
17859                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17860                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17861                    break;
17862                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17863                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17864                    break;
17865                default:
17866                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17867                    break;
17868            }
17869            int factor = numTrimming/3;
17870            int minFactor = 2;
17871            if (mHomeProcess != null) minFactor++;
17872            if (mPreviousProcess != null) minFactor++;
17873            if (factor < minFactor) factor = minFactor;
17874            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17875            for (int i=N-1; i>=0; i--) {
17876                ProcessRecord app = mLruProcesses.get(i);
17877                if (allChanged || app.procStateChanged) {
17878                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17879                    app.procStateChanged = false;
17880                }
17881                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17882                        && !app.killedByAm) {
17883                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17884                        try {
17885                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17886                                    "Trimming memory of " + app.processName
17887                                    + " to " + curLevel);
17888                            app.thread.scheduleTrimMemory(curLevel);
17889                        } catch (RemoteException e) {
17890                        }
17891                        if (false) {
17892                            // For now we won't do this; our memory trimming seems
17893                            // to be good enough at this point that destroying
17894                            // activities causes more harm than good.
17895                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17896                                    && app != mHomeProcess && app != mPreviousProcess) {
17897                                // Need to do this on its own message because the stack may not
17898                                // be in a consistent state at this point.
17899                                // For these apps we will also finish their activities
17900                                // to help them free memory.
17901                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17902                            }
17903                        }
17904                    }
17905                    app.trimMemoryLevel = curLevel;
17906                    step++;
17907                    if (step >= factor) {
17908                        step = 0;
17909                        switch (curLevel) {
17910                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17911                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17912                                break;
17913                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17914                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17915                                break;
17916                        }
17917                    }
17918                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17919                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17920                            && app.thread != null) {
17921                        try {
17922                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17923                                    "Trimming memory of heavy-weight " + app.processName
17924                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17925                            app.thread.scheduleTrimMemory(
17926                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17927                        } catch (RemoteException e) {
17928                        }
17929                    }
17930                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17931                } else {
17932                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17933                            || app.systemNoUi) && app.pendingUiClean) {
17934                        // If this application is now in the background and it
17935                        // had done UI, then give it the special trim level to
17936                        // have it free UI resources.
17937                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17938                        if (app.trimMemoryLevel < level && app.thread != null) {
17939                            try {
17940                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17941                                        "Trimming memory of bg-ui " + app.processName
17942                                        + " to " + level);
17943                                app.thread.scheduleTrimMemory(level);
17944                            } catch (RemoteException e) {
17945                            }
17946                        }
17947                        app.pendingUiClean = false;
17948                    }
17949                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17950                        try {
17951                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17952                                    "Trimming memory of fg " + app.processName
17953                                    + " to " + fgTrimLevel);
17954                            app.thread.scheduleTrimMemory(fgTrimLevel);
17955                        } catch (RemoteException e) {
17956                        }
17957                    }
17958                    app.trimMemoryLevel = fgTrimLevel;
17959                }
17960            }
17961        } else {
17962            if (mLowRamStartTime != 0) {
17963                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17964                mLowRamStartTime = 0;
17965            }
17966            for (int i=N-1; i>=0; i--) {
17967                ProcessRecord app = mLruProcesses.get(i);
17968                if (allChanged || app.procStateChanged) {
17969                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17970                    app.procStateChanged = false;
17971                }
17972                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17973                        || app.systemNoUi) && app.pendingUiClean) {
17974                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17975                            && app.thread != null) {
17976                        try {
17977                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17978                                    "Trimming memory of ui hidden " + app.processName
17979                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17980                            app.thread.scheduleTrimMemory(
17981                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17982                        } catch (RemoteException e) {
17983                        }
17984                    }
17985                    app.pendingUiClean = false;
17986                }
17987                app.trimMemoryLevel = 0;
17988            }
17989        }
17990
17991        if (mAlwaysFinishActivities) {
17992            // Need to do this on its own message because the stack may not
17993            // be in a consistent state at this point.
17994            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17995        }
17996
17997        if (allChanged) {
17998            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17999        }
18000
18001        if (mProcessStats.shouldWriteNowLocked(now)) {
18002            mHandler.post(new Runnable() {
18003                @Override public void run() {
18004                    synchronized (ActivityManagerService.this) {
18005                        mProcessStats.writeStateAsyncLocked();
18006                    }
18007                }
18008            });
18009        }
18010
18011        if (DEBUG_OOM_ADJ) {
18012            if (false) {
18013                RuntimeException here = new RuntimeException("here");
18014                here.fillInStackTrace();
18015                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18016            } else {
18017                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18018            }
18019        }
18020    }
18021
18022    final void trimApplications() {
18023        synchronized (this) {
18024            int i;
18025
18026            // First remove any unused application processes whose package
18027            // has been removed.
18028            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18029                final ProcessRecord app = mRemovedProcesses.get(i);
18030                if (app.activities.size() == 0
18031                        && app.curReceiver == null && app.services.size() == 0) {
18032                    Slog.i(
18033                        TAG, "Exiting empty application process "
18034                        + app.processName + " ("
18035                        + (app.thread != null ? app.thread.asBinder() : null)
18036                        + ")\n");
18037                    if (app.pid > 0 && app.pid != MY_PID) {
18038                        app.kill("empty", false);
18039                    } else {
18040                        try {
18041                            app.thread.scheduleExit();
18042                        } catch (Exception e) {
18043                            // Ignore exceptions.
18044                        }
18045                    }
18046                    cleanUpApplicationRecordLocked(app, false, true, -1);
18047                    mRemovedProcesses.remove(i);
18048
18049                    if (app.persistent) {
18050                        addAppLocked(app.info, false, null /* ABI override */);
18051                    }
18052                }
18053            }
18054
18055            // Now update the oom adj for all processes.
18056            updateOomAdjLocked();
18057        }
18058    }
18059
18060    /** This method sends the specified signal to each of the persistent apps */
18061    public void signalPersistentProcesses(int sig) throws RemoteException {
18062        if (sig != Process.SIGNAL_USR1) {
18063            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18064        }
18065
18066        synchronized (this) {
18067            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18068                    != PackageManager.PERMISSION_GRANTED) {
18069                throw new SecurityException("Requires permission "
18070                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18071            }
18072
18073            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18074                ProcessRecord r = mLruProcesses.get(i);
18075                if (r.thread != null && r.persistent) {
18076                    Process.sendSignal(r.pid, sig);
18077                }
18078            }
18079        }
18080    }
18081
18082    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18083        if (proc == null || proc == mProfileProc) {
18084            proc = mProfileProc;
18085            profileType = mProfileType;
18086            clearProfilerLocked();
18087        }
18088        if (proc == null) {
18089            return;
18090        }
18091        try {
18092            proc.thread.profilerControl(false, null, profileType);
18093        } catch (RemoteException e) {
18094            throw new IllegalStateException("Process disappeared");
18095        }
18096    }
18097
18098    private void clearProfilerLocked() {
18099        if (mProfileFd != null) {
18100            try {
18101                mProfileFd.close();
18102            } catch (IOException e) {
18103            }
18104        }
18105        mProfileApp = null;
18106        mProfileProc = null;
18107        mProfileFile = null;
18108        mProfileType = 0;
18109        mAutoStopProfiler = false;
18110        mSamplingInterval = 0;
18111    }
18112
18113    public boolean profileControl(String process, int userId, boolean start,
18114            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18115
18116        try {
18117            synchronized (this) {
18118                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18119                // its own permission.
18120                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18121                        != PackageManager.PERMISSION_GRANTED) {
18122                    throw new SecurityException("Requires permission "
18123                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18124                }
18125
18126                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18127                    throw new IllegalArgumentException("null profile info or fd");
18128                }
18129
18130                ProcessRecord proc = null;
18131                if (process != null) {
18132                    proc = findProcessLocked(process, userId, "profileControl");
18133                }
18134
18135                if (start && (proc == null || proc.thread == null)) {
18136                    throw new IllegalArgumentException("Unknown process: " + process);
18137                }
18138
18139                if (start) {
18140                    stopProfilerLocked(null, 0);
18141                    setProfileApp(proc.info, proc.processName, profilerInfo);
18142                    mProfileProc = proc;
18143                    mProfileType = profileType;
18144                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18145                    try {
18146                        fd = fd.dup();
18147                    } catch (IOException e) {
18148                        fd = null;
18149                    }
18150                    profilerInfo.profileFd = fd;
18151                    proc.thread.profilerControl(start, profilerInfo, profileType);
18152                    fd = null;
18153                    mProfileFd = null;
18154                } else {
18155                    stopProfilerLocked(proc, profileType);
18156                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18157                        try {
18158                            profilerInfo.profileFd.close();
18159                        } catch (IOException e) {
18160                        }
18161                    }
18162                }
18163
18164                return true;
18165            }
18166        } catch (RemoteException e) {
18167            throw new IllegalStateException("Process disappeared");
18168        } finally {
18169            if (profilerInfo != null && profilerInfo.profileFd != null) {
18170                try {
18171                    profilerInfo.profileFd.close();
18172                } catch (IOException e) {
18173                }
18174            }
18175        }
18176    }
18177
18178    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18179        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18180                userId, true, ALLOW_FULL_ONLY, callName, null);
18181        ProcessRecord proc = null;
18182        try {
18183            int pid = Integer.parseInt(process);
18184            synchronized (mPidsSelfLocked) {
18185                proc = mPidsSelfLocked.get(pid);
18186            }
18187        } catch (NumberFormatException e) {
18188        }
18189
18190        if (proc == null) {
18191            ArrayMap<String, SparseArray<ProcessRecord>> all
18192                    = mProcessNames.getMap();
18193            SparseArray<ProcessRecord> procs = all.get(process);
18194            if (procs != null && procs.size() > 0) {
18195                proc = procs.valueAt(0);
18196                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18197                    for (int i=1; i<procs.size(); i++) {
18198                        ProcessRecord thisProc = procs.valueAt(i);
18199                        if (thisProc.userId == userId) {
18200                            proc = thisProc;
18201                            break;
18202                        }
18203                    }
18204                }
18205            }
18206        }
18207
18208        return proc;
18209    }
18210
18211    public boolean dumpHeap(String process, int userId, boolean managed,
18212            String path, ParcelFileDescriptor fd) throws RemoteException {
18213
18214        try {
18215            synchronized (this) {
18216                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18217                // its own permission (same as profileControl).
18218                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18219                        != PackageManager.PERMISSION_GRANTED) {
18220                    throw new SecurityException("Requires permission "
18221                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18222                }
18223
18224                if (fd == null) {
18225                    throw new IllegalArgumentException("null fd");
18226                }
18227
18228                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18229                if (proc == null || proc.thread == null) {
18230                    throw new IllegalArgumentException("Unknown process: " + process);
18231                }
18232
18233                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18234                if (!isDebuggable) {
18235                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18236                        throw new SecurityException("Process not debuggable: " + proc);
18237                    }
18238                }
18239
18240                proc.thread.dumpHeap(managed, path, fd);
18241                fd = null;
18242                return true;
18243            }
18244        } catch (RemoteException e) {
18245            throw new IllegalStateException("Process disappeared");
18246        } finally {
18247            if (fd != null) {
18248                try {
18249                    fd.close();
18250                } catch (IOException e) {
18251                }
18252            }
18253        }
18254    }
18255
18256    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18257    public void monitor() {
18258        synchronized (this) { }
18259    }
18260
18261    void onCoreSettingsChange(Bundle settings) {
18262        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18263            ProcessRecord processRecord = mLruProcesses.get(i);
18264            try {
18265                if (processRecord.thread != null) {
18266                    processRecord.thread.setCoreSettings(settings);
18267                }
18268            } catch (RemoteException re) {
18269                /* ignore */
18270            }
18271        }
18272    }
18273
18274    // Multi-user methods
18275
18276    /**
18277     * Start user, if its not already running, but don't bring it to foreground.
18278     */
18279    @Override
18280    public boolean startUserInBackground(final int userId) {
18281        return startUser(userId, /* foreground */ false);
18282    }
18283
18284    /**
18285     * Start user, if its not already running, and bring it to foreground.
18286     */
18287    boolean startUserInForeground(final int userId, Dialog dlg) {
18288        boolean result = startUser(userId, /* foreground */ true);
18289        dlg.dismiss();
18290        return result;
18291    }
18292
18293    /**
18294     * Refreshes the list of users related to the current user when either a
18295     * user switch happens or when a new related user is started in the
18296     * background.
18297     */
18298    private void updateCurrentProfileIdsLocked() {
18299        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18300                mCurrentUserId, false /* enabledOnly */);
18301        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18302        for (int i = 0; i < currentProfileIds.length; i++) {
18303            currentProfileIds[i] = profiles.get(i).id;
18304        }
18305        mCurrentProfileIds = currentProfileIds;
18306
18307        synchronized (mUserProfileGroupIdsSelfLocked) {
18308            mUserProfileGroupIdsSelfLocked.clear();
18309            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18310            for (int i = 0; i < users.size(); i++) {
18311                UserInfo user = users.get(i);
18312                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18313                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18314                }
18315            }
18316        }
18317    }
18318
18319    private Set getProfileIdsLocked(int userId) {
18320        Set userIds = new HashSet<Integer>();
18321        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18322                userId, false /* enabledOnly */);
18323        for (UserInfo user : profiles) {
18324            userIds.add(Integer.valueOf(user.id));
18325        }
18326        return userIds;
18327    }
18328
18329    @Override
18330    public boolean switchUser(final int userId) {
18331        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18332        String userName;
18333        synchronized (this) {
18334            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18335            if (userInfo == null) {
18336                Slog.w(TAG, "No user info for user #" + userId);
18337                return false;
18338            }
18339            if (userInfo.isManagedProfile()) {
18340                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18341                return false;
18342            }
18343            userName = userInfo.name;
18344            mTargetUserId = userId;
18345        }
18346        mHandler.removeMessages(START_USER_SWITCH_MSG);
18347        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18348        return true;
18349    }
18350
18351    private void showUserSwitchDialog(int userId, String userName) {
18352        // The dialog will show and then initiate the user switch by calling startUserInForeground
18353        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18354                true /* above system */);
18355        d.show();
18356    }
18357
18358    private boolean startUser(final int userId, final boolean foreground) {
18359        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18360                != PackageManager.PERMISSION_GRANTED) {
18361            String msg = "Permission Denial: switchUser() from pid="
18362                    + Binder.getCallingPid()
18363                    + ", uid=" + Binder.getCallingUid()
18364                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18365            Slog.w(TAG, msg);
18366            throw new SecurityException(msg);
18367        }
18368
18369        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18370
18371        final long ident = Binder.clearCallingIdentity();
18372        try {
18373            synchronized (this) {
18374                final int oldUserId = mCurrentUserId;
18375                if (oldUserId == userId) {
18376                    return true;
18377                }
18378
18379                mStackSupervisor.setLockTaskModeLocked(null, false);
18380
18381                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18382                if (userInfo == null) {
18383                    Slog.w(TAG, "No user info for user #" + userId);
18384                    return false;
18385                }
18386                if (foreground && userInfo.isManagedProfile()) {
18387                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18388                    return false;
18389                }
18390
18391                if (foreground) {
18392                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18393                            R.anim.screen_user_enter);
18394                }
18395
18396                boolean needStart = false;
18397
18398                // If the user we are switching to is not currently started, then
18399                // we need to start it now.
18400                if (mStartedUsers.get(userId) == null) {
18401                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18402                    updateStartedUserArrayLocked();
18403                    needStart = true;
18404                }
18405
18406                final Integer userIdInt = Integer.valueOf(userId);
18407                mUserLru.remove(userIdInt);
18408                mUserLru.add(userIdInt);
18409
18410                if (foreground) {
18411                    mCurrentUserId = userId;
18412                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18413                    updateCurrentProfileIdsLocked();
18414                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18415                    // Once the internal notion of the active user has switched, we lock the device
18416                    // with the option to show the user switcher on the keyguard.
18417                    mWindowManager.lockNow(null);
18418                } else {
18419                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18420                    updateCurrentProfileIdsLocked();
18421                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18422                    mUserLru.remove(currentUserIdInt);
18423                    mUserLru.add(currentUserIdInt);
18424                }
18425
18426                final UserStartedState uss = mStartedUsers.get(userId);
18427
18428                // Make sure user is in the started state.  If it is currently
18429                // stopping, we need to knock that off.
18430                if (uss.mState == UserStartedState.STATE_STOPPING) {
18431                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18432                    // so we can just fairly silently bring the user back from
18433                    // the almost-dead.
18434                    uss.mState = UserStartedState.STATE_RUNNING;
18435                    updateStartedUserArrayLocked();
18436                    needStart = true;
18437                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18438                    // This means ACTION_SHUTDOWN has been sent, so we will
18439                    // need to treat this as a new boot of the user.
18440                    uss.mState = UserStartedState.STATE_BOOTING;
18441                    updateStartedUserArrayLocked();
18442                    needStart = true;
18443                }
18444
18445                if (uss.mState == UserStartedState.STATE_BOOTING) {
18446                    // Booting up a new user, need to tell system services about it.
18447                    // Note that this is on the same handler as scheduling of broadcasts,
18448                    // which is important because it needs to go first.
18449                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18450                }
18451
18452                if (foreground) {
18453                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18454                            oldUserId));
18455                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18456                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18457                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18458                            oldUserId, userId, uss));
18459                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18460                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18461                }
18462
18463                if (needStart) {
18464                    // Send USER_STARTED broadcast
18465                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18466                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18467                            | Intent.FLAG_RECEIVER_FOREGROUND);
18468                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18469                    broadcastIntentLocked(null, null, intent,
18470                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18471                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18472                }
18473
18474                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18475                    if (userId != UserHandle.USER_OWNER) {
18476                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18477                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18478                        broadcastIntentLocked(null, null, intent, null,
18479                                new IIntentReceiver.Stub() {
18480                                    public void performReceive(Intent intent, int resultCode,
18481                                            String data, Bundle extras, boolean ordered,
18482                                            boolean sticky, int sendingUser) {
18483                                        onUserInitialized(uss, foreground, oldUserId, userId);
18484                                    }
18485                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18486                                true, false, MY_PID, Process.SYSTEM_UID,
18487                                userId);
18488                        uss.initializing = true;
18489                    } else {
18490                        getUserManagerLocked().makeInitialized(userInfo.id);
18491                    }
18492                }
18493
18494                if (foreground) {
18495                    if (!uss.initializing) {
18496                        moveUserToForeground(uss, oldUserId, userId);
18497                    }
18498                } else {
18499                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18500                }
18501
18502                if (needStart) {
18503                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18504                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18505                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18506                    broadcastIntentLocked(null, null, intent,
18507                            null, new IIntentReceiver.Stub() {
18508                                @Override
18509                                public void performReceive(Intent intent, int resultCode, String data,
18510                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18511                                        throws RemoteException {
18512                                }
18513                            }, 0, null, null,
18514                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18515                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18516                }
18517            }
18518        } finally {
18519            Binder.restoreCallingIdentity(ident);
18520        }
18521
18522        return true;
18523    }
18524
18525    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18526        long ident = Binder.clearCallingIdentity();
18527        try {
18528            Intent intent;
18529            if (oldUserId >= 0) {
18530                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18531                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18532                int count = profiles.size();
18533                for (int i = 0; i < count; i++) {
18534                    int profileUserId = profiles.get(i).id;
18535                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18536                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18537                            | Intent.FLAG_RECEIVER_FOREGROUND);
18538                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18539                    broadcastIntentLocked(null, null, intent,
18540                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18541                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18542                }
18543            }
18544            if (newUserId >= 0) {
18545                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18546                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18547                int count = profiles.size();
18548                for (int i = 0; i < count; i++) {
18549                    int profileUserId = profiles.get(i).id;
18550                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18551                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18552                            | Intent.FLAG_RECEIVER_FOREGROUND);
18553                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18554                    broadcastIntentLocked(null, null, intent,
18555                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18556                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18557                }
18558                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18559                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18560                        | Intent.FLAG_RECEIVER_FOREGROUND);
18561                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18562                broadcastIntentLocked(null, null, intent,
18563                        null, null, 0, null, null,
18564                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18565                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18566            }
18567        } finally {
18568            Binder.restoreCallingIdentity(ident);
18569        }
18570    }
18571
18572    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18573            final int newUserId) {
18574        final int N = mUserSwitchObservers.beginBroadcast();
18575        if (N > 0) {
18576            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18577                int mCount = 0;
18578                @Override
18579                public void sendResult(Bundle data) throws RemoteException {
18580                    synchronized (ActivityManagerService.this) {
18581                        if (mCurUserSwitchCallback == this) {
18582                            mCount++;
18583                            if (mCount == N) {
18584                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18585                            }
18586                        }
18587                    }
18588                }
18589            };
18590            synchronized (this) {
18591                uss.switching = true;
18592                mCurUserSwitchCallback = callback;
18593            }
18594            for (int i=0; i<N; i++) {
18595                try {
18596                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18597                            newUserId, callback);
18598                } catch (RemoteException e) {
18599                }
18600            }
18601        } else {
18602            synchronized (this) {
18603                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18604            }
18605        }
18606        mUserSwitchObservers.finishBroadcast();
18607    }
18608
18609    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18610        synchronized (this) {
18611            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18612            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18613        }
18614    }
18615
18616    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18617        mCurUserSwitchCallback = null;
18618        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18619        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18620                oldUserId, newUserId, uss));
18621    }
18622
18623    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18624        synchronized (this) {
18625            if (foreground) {
18626                moveUserToForeground(uss, oldUserId, newUserId);
18627            }
18628        }
18629
18630        completeSwitchAndInitalize(uss, newUserId, true, false);
18631    }
18632
18633    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18634        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18635        if (homeInFront) {
18636            startHomeActivityLocked(newUserId);
18637        } else {
18638            mStackSupervisor.resumeTopActivitiesLocked();
18639        }
18640        EventLogTags.writeAmSwitchUser(newUserId);
18641        getUserManagerLocked().userForeground(newUserId);
18642        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18643    }
18644
18645    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18646        completeSwitchAndInitalize(uss, newUserId, false, true);
18647    }
18648
18649    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18650            boolean clearInitializing, boolean clearSwitching) {
18651        boolean unfrozen = false;
18652        synchronized (this) {
18653            if (clearInitializing) {
18654                uss.initializing = false;
18655                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18656            }
18657            if (clearSwitching) {
18658                uss.switching = false;
18659            }
18660            if (!uss.switching && !uss.initializing) {
18661                mWindowManager.stopFreezingScreen();
18662                unfrozen = true;
18663            }
18664        }
18665        if (unfrozen) {
18666            final int N = mUserSwitchObservers.beginBroadcast();
18667            for (int i=0; i<N; i++) {
18668                try {
18669                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18670                } catch (RemoteException e) {
18671                }
18672            }
18673            mUserSwitchObservers.finishBroadcast();
18674        }
18675    }
18676
18677    void scheduleStartProfilesLocked() {
18678        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18679            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18680                    DateUtils.SECOND_IN_MILLIS);
18681        }
18682    }
18683
18684    void startProfilesLocked() {
18685        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18686        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18687                mCurrentUserId, false /* enabledOnly */);
18688        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18689        for (UserInfo user : profiles) {
18690            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18691                    && user.id != mCurrentUserId) {
18692                toStart.add(user);
18693            }
18694        }
18695        final int n = toStart.size();
18696        int i = 0;
18697        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18698            startUserInBackground(toStart.get(i).id);
18699        }
18700        if (i < n) {
18701            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18702        }
18703    }
18704
18705    void finishUserBoot(UserStartedState uss) {
18706        synchronized (this) {
18707            if (uss.mState == UserStartedState.STATE_BOOTING
18708                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18709                uss.mState = UserStartedState.STATE_RUNNING;
18710                final int userId = uss.mHandle.getIdentifier();
18711                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18712                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18713                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18714                broadcastIntentLocked(null, null, intent,
18715                        null, null, 0, null, null,
18716                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18717                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18718            }
18719        }
18720    }
18721
18722    void finishUserSwitch(UserStartedState uss) {
18723        synchronized (this) {
18724            finishUserBoot(uss);
18725
18726            startProfilesLocked();
18727
18728            int num = mUserLru.size();
18729            int i = 0;
18730            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18731                Integer oldUserId = mUserLru.get(i);
18732                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18733                if (oldUss == null) {
18734                    // Shouldn't happen, but be sane if it does.
18735                    mUserLru.remove(i);
18736                    num--;
18737                    continue;
18738                }
18739                if (oldUss.mState == UserStartedState.STATE_STOPPING
18740                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18741                    // This user is already stopping, doesn't count.
18742                    num--;
18743                    i++;
18744                    continue;
18745                }
18746                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18747                    // Owner and current can't be stopped, but count as running.
18748                    i++;
18749                    continue;
18750                }
18751                // This is a user to be stopped.
18752                stopUserLocked(oldUserId, null);
18753                num--;
18754                i++;
18755            }
18756        }
18757    }
18758
18759    @Override
18760    public int stopUser(final int userId, final IStopUserCallback callback) {
18761        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18762                != PackageManager.PERMISSION_GRANTED) {
18763            String msg = "Permission Denial: switchUser() from pid="
18764                    + Binder.getCallingPid()
18765                    + ", uid=" + Binder.getCallingUid()
18766                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18767            Slog.w(TAG, msg);
18768            throw new SecurityException(msg);
18769        }
18770        if (userId <= 0) {
18771            throw new IllegalArgumentException("Can't stop primary user " + userId);
18772        }
18773        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18774        synchronized (this) {
18775            return stopUserLocked(userId, callback);
18776        }
18777    }
18778
18779    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18780        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18781        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18782            return ActivityManager.USER_OP_IS_CURRENT;
18783        }
18784
18785        final UserStartedState uss = mStartedUsers.get(userId);
18786        if (uss == null) {
18787            // User is not started, nothing to do...  but we do need to
18788            // callback if requested.
18789            if (callback != null) {
18790                mHandler.post(new Runnable() {
18791                    @Override
18792                    public void run() {
18793                        try {
18794                            callback.userStopped(userId);
18795                        } catch (RemoteException e) {
18796                        }
18797                    }
18798                });
18799            }
18800            return ActivityManager.USER_OP_SUCCESS;
18801        }
18802
18803        if (callback != null) {
18804            uss.mStopCallbacks.add(callback);
18805        }
18806
18807        if (uss.mState != UserStartedState.STATE_STOPPING
18808                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18809            uss.mState = UserStartedState.STATE_STOPPING;
18810            updateStartedUserArrayLocked();
18811
18812            long ident = Binder.clearCallingIdentity();
18813            try {
18814                // We are going to broadcast ACTION_USER_STOPPING and then
18815                // once that is done send a final ACTION_SHUTDOWN and then
18816                // stop the user.
18817                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18818                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18819                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18820                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18821                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18822                // This is the result receiver for the final shutdown broadcast.
18823                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18824                    @Override
18825                    public void performReceive(Intent intent, int resultCode, String data,
18826                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18827                        finishUserStop(uss);
18828                    }
18829                };
18830                // This is the result receiver for the initial stopping broadcast.
18831                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18832                    @Override
18833                    public void performReceive(Intent intent, int resultCode, String data,
18834                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18835                        // On to the next.
18836                        synchronized (ActivityManagerService.this) {
18837                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18838                                // Whoops, we are being started back up.  Abort, abort!
18839                                return;
18840                            }
18841                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18842                        }
18843                        mBatteryStatsService.noteEvent(
18844                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18845                                Integer.toString(userId), userId);
18846                        mSystemServiceManager.stopUser(userId);
18847                        broadcastIntentLocked(null, null, shutdownIntent,
18848                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18849                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18850                    }
18851                };
18852                // Kick things off.
18853                broadcastIntentLocked(null, null, stoppingIntent,
18854                        null, stoppingReceiver, 0, null, null,
18855                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18856                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18857            } finally {
18858                Binder.restoreCallingIdentity(ident);
18859            }
18860        }
18861
18862        return ActivityManager.USER_OP_SUCCESS;
18863    }
18864
18865    void finishUserStop(UserStartedState uss) {
18866        final int userId = uss.mHandle.getIdentifier();
18867        boolean stopped;
18868        ArrayList<IStopUserCallback> callbacks;
18869        synchronized (this) {
18870            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18871            if (mStartedUsers.get(userId) != uss) {
18872                stopped = false;
18873            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18874                stopped = false;
18875            } else {
18876                stopped = true;
18877                // User can no longer run.
18878                mStartedUsers.remove(userId);
18879                mUserLru.remove(Integer.valueOf(userId));
18880                updateStartedUserArrayLocked();
18881
18882                // Clean up all state and processes associated with the user.
18883                // Kill all the processes for the user.
18884                forceStopUserLocked(userId, "finish user");
18885            }
18886
18887            // Explicitly remove the old information in mRecentTasks.
18888            removeRecentTasksForUserLocked(userId);
18889        }
18890
18891        for (int i=0; i<callbacks.size(); i++) {
18892            try {
18893                if (stopped) callbacks.get(i).userStopped(userId);
18894                else callbacks.get(i).userStopAborted(userId);
18895            } catch (RemoteException e) {
18896            }
18897        }
18898
18899        if (stopped) {
18900            mSystemServiceManager.cleanupUser(userId);
18901            synchronized (this) {
18902                mStackSupervisor.removeUserLocked(userId);
18903            }
18904        }
18905    }
18906
18907    @Override
18908    public UserInfo getCurrentUser() {
18909        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18910                != PackageManager.PERMISSION_GRANTED) && (
18911                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18912                != PackageManager.PERMISSION_GRANTED)) {
18913            String msg = "Permission Denial: getCurrentUser() from pid="
18914                    + Binder.getCallingPid()
18915                    + ", uid=" + Binder.getCallingUid()
18916                    + " requires " + INTERACT_ACROSS_USERS;
18917            Slog.w(TAG, msg);
18918            throw new SecurityException(msg);
18919        }
18920        synchronized (this) {
18921            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18922            return getUserManagerLocked().getUserInfo(userId);
18923        }
18924    }
18925
18926    int getCurrentUserIdLocked() {
18927        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18928    }
18929
18930    @Override
18931    public boolean isUserRunning(int userId, boolean orStopped) {
18932        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18933                != PackageManager.PERMISSION_GRANTED) {
18934            String msg = "Permission Denial: isUserRunning() from pid="
18935                    + Binder.getCallingPid()
18936                    + ", uid=" + Binder.getCallingUid()
18937                    + " requires " + INTERACT_ACROSS_USERS;
18938            Slog.w(TAG, msg);
18939            throw new SecurityException(msg);
18940        }
18941        synchronized (this) {
18942            return isUserRunningLocked(userId, orStopped);
18943        }
18944    }
18945
18946    boolean isUserRunningLocked(int userId, boolean orStopped) {
18947        UserStartedState state = mStartedUsers.get(userId);
18948        if (state == null) {
18949            return false;
18950        }
18951        if (orStopped) {
18952            return true;
18953        }
18954        return state.mState != UserStartedState.STATE_STOPPING
18955                && state.mState != UserStartedState.STATE_SHUTDOWN;
18956    }
18957
18958    @Override
18959    public int[] getRunningUserIds() {
18960        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18961                != PackageManager.PERMISSION_GRANTED) {
18962            String msg = "Permission Denial: isUserRunning() from pid="
18963                    + Binder.getCallingPid()
18964                    + ", uid=" + Binder.getCallingUid()
18965                    + " requires " + INTERACT_ACROSS_USERS;
18966            Slog.w(TAG, msg);
18967            throw new SecurityException(msg);
18968        }
18969        synchronized (this) {
18970            return mStartedUserArray;
18971        }
18972    }
18973
18974    private void updateStartedUserArrayLocked() {
18975        int num = 0;
18976        for (int i=0; i<mStartedUsers.size();  i++) {
18977            UserStartedState uss = mStartedUsers.valueAt(i);
18978            // This list does not include stopping users.
18979            if (uss.mState != UserStartedState.STATE_STOPPING
18980                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18981                num++;
18982            }
18983        }
18984        mStartedUserArray = new int[num];
18985        num = 0;
18986        for (int i=0; i<mStartedUsers.size();  i++) {
18987            UserStartedState uss = mStartedUsers.valueAt(i);
18988            if (uss.mState != UserStartedState.STATE_STOPPING
18989                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18990                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18991                num++;
18992            }
18993        }
18994    }
18995
18996    @Override
18997    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18998        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18999                != PackageManager.PERMISSION_GRANTED) {
19000            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19001                    + Binder.getCallingPid()
19002                    + ", uid=" + Binder.getCallingUid()
19003                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19004            Slog.w(TAG, msg);
19005            throw new SecurityException(msg);
19006        }
19007
19008        mUserSwitchObservers.register(observer);
19009    }
19010
19011    @Override
19012    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19013        mUserSwitchObservers.unregister(observer);
19014    }
19015
19016    private boolean userExists(int userId) {
19017        if (userId == 0) {
19018            return true;
19019        }
19020        UserManagerService ums = getUserManagerLocked();
19021        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19022    }
19023
19024    int[] getUsersLocked() {
19025        UserManagerService ums = getUserManagerLocked();
19026        return ums != null ? ums.getUserIds() : new int[] { 0 };
19027    }
19028
19029    UserManagerService getUserManagerLocked() {
19030        if (mUserManager == null) {
19031            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19032            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19033        }
19034        return mUserManager;
19035    }
19036
19037    private int applyUserId(int uid, int userId) {
19038        return UserHandle.getUid(userId, uid);
19039    }
19040
19041    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19042        if (info == null) return null;
19043        ApplicationInfo newInfo = new ApplicationInfo(info);
19044        newInfo.uid = applyUserId(info.uid, userId);
19045        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19046                + info.packageName;
19047        return newInfo;
19048    }
19049
19050    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19051        if (aInfo == null
19052                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19053            return aInfo;
19054        }
19055
19056        ActivityInfo info = new ActivityInfo(aInfo);
19057        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19058        return info;
19059    }
19060
19061    private final class LocalService extends ActivityManagerInternal {
19062        @Override
19063        public void goingToSleep() {
19064            ActivityManagerService.this.goingToSleep();
19065        }
19066
19067        @Override
19068        public void wakingUp() {
19069            ActivityManagerService.this.wakingUp();
19070        }
19071
19072        @Override
19073        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19074                String processName, String abiOverride, int uid, Runnable crashHandler) {
19075            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19076                    processName, abiOverride, uid, crashHandler);
19077        }
19078    }
19079
19080    /**
19081     * An implementation of IAppTask, that allows an app to manage its own tasks via
19082     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19083     * only the process that calls getAppTasks() can call the AppTask methods.
19084     */
19085    class AppTaskImpl extends IAppTask.Stub {
19086        private int mTaskId;
19087        private int mCallingUid;
19088
19089        public AppTaskImpl(int taskId, int callingUid) {
19090            mTaskId = taskId;
19091            mCallingUid = callingUid;
19092        }
19093
19094        private void checkCaller() {
19095            if (mCallingUid != Binder.getCallingUid()) {
19096                throw new SecurityException("Caller " + mCallingUid
19097                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19098            }
19099        }
19100
19101        @Override
19102        public void finishAndRemoveTask() {
19103            checkCaller();
19104
19105            synchronized (ActivityManagerService.this) {
19106                long origId = Binder.clearCallingIdentity();
19107                try {
19108                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19109                    if (tr == null) {
19110                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19111                    }
19112                    // Only kill the process if we are not a new document
19113                    int flags = tr.getBaseIntent().getFlags();
19114                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
19115                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
19116                    removeTaskByIdLocked(mTaskId,
19117                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
19118                } finally {
19119                    Binder.restoreCallingIdentity(origId);
19120                }
19121            }
19122        }
19123
19124        @Override
19125        public ActivityManager.RecentTaskInfo getTaskInfo() {
19126            checkCaller();
19127
19128            synchronized (ActivityManagerService.this) {
19129                long origId = Binder.clearCallingIdentity();
19130                try {
19131                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19132                    if (tr == null) {
19133                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19134                    }
19135                    return createRecentTaskInfoFromTaskRecord(tr);
19136                } finally {
19137                    Binder.restoreCallingIdentity(origId);
19138                }
19139            }
19140        }
19141
19142        @Override
19143        public void moveToFront() {
19144            checkCaller();
19145
19146            final TaskRecord tr;
19147            synchronized (ActivityManagerService.this) {
19148                tr = recentTaskForIdLocked(mTaskId);
19149                if (tr == null) {
19150                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19151                }
19152                if (tr.getRootActivity() != null) {
19153                    moveTaskToFrontLocked(tr.taskId, 0, null);
19154                    return;
19155                }
19156            }
19157
19158            startActivityFromRecentsInner(tr.taskId, null);
19159        }
19160
19161        @Override
19162        public int startActivity(IBinder whoThread, String callingPackage,
19163                Intent intent, String resolvedType, Bundle options) {
19164            checkCaller();
19165
19166            int callingUser = UserHandle.getCallingUserId();
19167            TaskRecord tr;
19168            IApplicationThread appThread;
19169            synchronized (ActivityManagerService.this) {
19170                tr = recentTaskForIdLocked(mTaskId);
19171                if (tr == null) {
19172                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19173                }
19174                appThread = ApplicationThreadNative.asInterface(whoThread);
19175                if (appThread == null) {
19176                    throw new IllegalArgumentException("Bad app thread " + appThread);
19177                }
19178            }
19179            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19180                    resolvedType, null, null, null, null, 0, 0, null, null,
19181                    null, options, callingUser, null, tr);
19182        }
19183
19184        @Override
19185        public void setExcludeFromRecents(boolean exclude) {
19186            checkCaller();
19187
19188            synchronized (ActivityManagerService.this) {
19189                long origId = Binder.clearCallingIdentity();
19190                try {
19191                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19192                    if (tr == null) {
19193                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19194                    }
19195                    Intent intent = tr.getBaseIntent();
19196                    if (exclude) {
19197                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19198                    } else {
19199                        intent.setFlags(intent.getFlags()
19200                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19201                    }
19202                } finally {
19203                    Binder.restoreCallingIdentity(origId);
19204                }
19205            }
19206        }
19207    }
19208}
19209