ActivityManagerService.java revision 42dc85a848285b021d03179131efe416e804cc6b
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.UserManagerService;
85import com.android.server.wm.AppTransition;
86import com.android.server.wm.WindowManagerService;
87import com.google.android.collect.Lists;
88import com.google.android.collect.Maps;
89
90import libcore.io.IoUtils;
91
92import org.xmlpull.v1.XmlPullParser;
93import org.xmlpull.v1.XmlPullParserException;
94import org.xmlpull.v1.XmlSerializer;
95
96import android.app.Activity;
97import android.app.ActivityManager;
98import android.app.ActivityManager.RunningTaskInfo;
99import android.app.ActivityManager.StackInfo;
100import android.app.ActivityManagerInternal;
101import android.app.ActivityManagerNative;
102import android.app.ActivityOptions;
103import android.app.ActivityThread;
104import android.app.AlertDialog;
105import android.app.AppGlobals;
106import android.app.ApplicationErrorReport;
107import android.app.Dialog;
108import android.app.IActivityController;
109import android.app.IApplicationThread;
110import android.app.IInstrumentationWatcher;
111import android.app.INotificationManager;
112import android.app.IProcessObserver;
113import android.app.IServiceConnection;
114import android.app.IStopUserCallback;
115import android.app.IUiAutomationConnection;
116import android.app.IUserSwitchObserver;
117import android.app.Instrumentation;
118import android.app.Notification;
119import android.app.NotificationManager;
120import android.app.PendingIntent;
121import android.app.backup.IBackupManager;
122import android.content.ActivityNotFoundException;
123import android.content.BroadcastReceiver;
124import android.content.ClipData;
125import android.content.ComponentCallbacks2;
126import android.content.ComponentName;
127import android.content.ContentProvider;
128import android.content.ContentResolver;
129import android.content.Context;
130import android.content.DialogInterface;
131import android.content.IContentProvider;
132import android.content.IIntentReceiver;
133import android.content.IIntentSender;
134import android.content.Intent;
135import android.content.IntentFilter;
136import android.content.IntentSender;
137import android.content.pm.ActivityInfo;
138import android.content.pm.ApplicationInfo;
139import android.content.pm.ConfigurationInfo;
140import android.content.pm.IPackageDataObserver;
141import android.content.pm.IPackageManager;
142import android.content.pm.InstrumentationInfo;
143import android.content.pm.PackageInfo;
144import android.content.pm.PackageManager;
145import android.content.pm.ParceledListSlice;
146import android.content.pm.UserInfo;
147import android.content.pm.PackageManager.NameNotFoundException;
148import android.content.pm.PathPermission;
149import android.content.pm.ProviderInfo;
150import android.content.pm.ResolveInfo;
151import android.content.pm.ServiceInfo;
152import android.content.res.CompatibilityInfo;
153import android.content.res.Configuration;
154import android.net.Proxy;
155import android.net.ProxyInfo;
156import android.net.Uri;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IRemoteCallback;
170import android.os.IUserManager;
171import android.os.Looper;
172import android.os.Message;
173import android.os.Parcel;
174import android.os.ParcelFileDescriptor;
175import android.os.Process;
176import android.os.RemoteCallbackList;
177import android.os.RemoteException;
178import android.os.SELinux;
179import android.os.ServiceManager;
180import android.os.StrictMode;
181import android.os.SystemClock;
182import android.os.SystemProperties;
183import android.os.UpdateLock;
184import android.os.UserHandle;
185import android.os.UserManager;
186import android.provider.Settings;
187import android.text.format.DateUtils;
188import android.text.format.Time;
189import android.util.AtomicFile;
190import android.util.EventLog;
191import android.util.Log;
192import android.util.Pair;
193import android.util.PrintWriterPrinter;
194import android.util.Slog;
195import android.util.SparseArray;
196import android.util.TimeUtils;
197import android.util.Xml;
198import android.view.Gravity;
199import android.view.LayoutInflater;
200import android.view.View;
201import android.view.WindowManager;
202import dalvik.system.VMRuntime;
203
204import java.io.BufferedInputStream;
205import java.io.BufferedOutputStream;
206import java.io.DataInputStream;
207import java.io.DataOutputStream;
208import java.io.File;
209import java.io.FileDescriptor;
210import java.io.FileInputStream;
211import java.io.FileNotFoundException;
212import java.io.FileOutputStream;
213import java.io.IOException;
214import java.io.InputStreamReader;
215import java.io.PrintWriter;
216import java.io.StringWriter;
217import java.lang.ref.WeakReference;
218import java.util.ArrayList;
219import java.util.Arrays;
220import java.util.Collections;
221import java.util.Comparator;
222import java.util.HashMap;
223import java.util.HashSet;
224import java.util.Iterator;
225import java.util.List;
226import java.util.Locale;
227import java.util.Map;
228import java.util.Set;
229import java.util.concurrent.atomic.AtomicBoolean;
230import java.util.concurrent.atomic.AtomicLong;
231
232public final class ActivityManagerService extends ActivityManagerNative
233        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
234
235    private static final String USER_DATA_DIR = "/data/user/";
236    // File that stores last updated system version and called preboot receivers
237    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
238
239    static final String TAG = "ActivityManager";
240    static final String TAG_MU = "ActivityManagerServiceMU";
241    static final boolean DEBUG = false;
242    static final boolean localLOGV = DEBUG;
243    static final boolean DEBUG_BACKUP = localLOGV || false;
244    static final boolean DEBUG_BROADCAST = localLOGV || false;
245    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
246    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
247    static final boolean DEBUG_CLEANUP = localLOGV || false;
248    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
249    static final boolean DEBUG_FOCUS = false;
250    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
251    static final boolean DEBUG_MU = localLOGV || false;
252    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
253    static final boolean DEBUG_LRU = localLOGV || false;
254    static final boolean DEBUG_PAUSE = localLOGV || false;
255    static final boolean DEBUG_POWER = localLOGV || false;
256    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
257    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
258    static final boolean DEBUG_PROCESSES = localLOGV || false;
259    static final boolean DEBUG_PROVIDER = localLOGV || false;
260    static final boolean DEBUG_RESULTS = localLOGV || false;
261    static final boolean DEBUG_SERVICE = localLOGV || false;
262    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
263    static final boolean DEBUG_STACK = localLOGV || false;
264    static final boolean DEBUG_SWITCH = localLOGV || false;
265    static final boolean DEBUG_TASKS = localLOGV || false;
266    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
267    static final boolean DEBUG_TRANSITION = localLOGV || false;
268    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
269    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
270    static final boolean DEBUG_VISBILITY = localLOGV || false;
271    static final boolean DEBUG_PSS = localLOGV || false;
272    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
273    static final boolean DEBUG_RECENTS = localLOGV || false;
274    static final boolean VALIDATE_TOKENS = false;
275    static final boolean SHOW_ACTIVITY_START_TIME = true;
276
277    // Control over CPU and battery monitoring.
278    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
279    static final boolean MONITOR_CPU_USAGE = true;
280    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
281    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
282    static final boolean MONITOR_THREAD_CPU_USAGE = false;
283
284    // The flags that are set for all calls we make to the package manager.
285    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
286
287    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
288
289    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
290
291    // Maximum number recent bitmaps to keep in memory.
292    static final int MAX_RECENT_BITMAPS = 5;
293
294    // Amount of time after a call to stopAppSwitches() during which we will
295    // prevent further untrusted switches from happening.
296    static final long APP_SWITCH_DELAY_TIME = 5*1000;
297
298    // How long we wait for a launched process to attach to the activity manager
299    // before we decide it's never going to come up for real.
300    static final int PROC_START_TIMEOUT = 10*1000;
301
302    // How long we wait for a launched process to attach to the activity manager
303    // before we decide it's never going to come up for real, when the process was
304    // started with a wrapper for instrumentation (such as Valgrind) because it
305    // could take much longer than usual.
306    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
307
308    // How long to wait after going idle before forcing apps to GC.
309    static final int GC_TIMEOUT = 5*1000;
310
311    // The minimum amount of time between successive GC requests for a process.
312    static final int GC_MIN_INTERVAL = 60*1000;
313
314    // The minimum amount of time between successive PSS requests for a process.
315    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
316
317    // The minimum amount of time between successive PSS requests for a process
318    // when the request is due to the memory state being lowered.
319    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
320
321    // The rate at which we check for apps using excessive power -- 15 mins.
322    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
323
324    // The minimum sample duration we will allow before deciding we have
325    // enough data on wake locks to start killing things.
326    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
327
328    // The minimum sample duration we will allow before deciding we have
329    // enough data on CPU usage to start killing things.
330    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
331
332    // How long we allow a receiver to run before giving up on it.
333    static final int BROADCAST_FG_TIMEOUT = 10*1000;
334    static final int BROADCAST_BG_TIMEOUT = 60*1000;
335
336    // How long we wait until we timeout on key dispatching.
337    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
338
339    // How long we wait until we timeout on key dispatching during instrumentation.
340    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
341
342    // Amount of time we wait for observers to handle a user switch before
343    // giving up on them and unfreezing the screen.
344    static final int USER_SWITCH_TIMEOUT = 2*1000;
345
346    // Maximum number of users we allow to be running at a time.
347    static final int MAX_RUNNING_USERS = 3;
348
349    // How long to wait in getAssistContextExtras for the activity and foreground services
350    // to respond with the result.
351    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
352
353    // Maximum number of persisted Uri grants a package is allowed
354    static final int MAX_PERSISTED_URI_GRANTS = 128;
355
356    static final int MY_PID = Process.myPid();
357
358    static final String[] EMPTY_STRING_ARRAY = new String[0];
359
360    // How many bytes to write into the dropbox log before truncating
361    static final int DROPBOX_MAX_SIZE = 256 * 1024;
362
363    // Access modes for handleIncomingUser.
364    static final int ALLOW_NON_FULL = 0;
365    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
366    static final int ALLOW_FULL_ONLY = 2;
367
368    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
369
370    /** All system services */
371    SystemServiceManager mSystemServiceManager;
372
373    /** Run all ActivityStacks through this */
374    ActivityStackSupervisor mStackSupervisor;
375
376    public IntentFirewall mIntentFirewall;
377
378    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
379    // default actuion automatically.  Important for devices without direct input
380    // devices.
381    private boolean mShowDialogs = true;
382
383    BroadcastQueue mFgBroadcastQueue;
384    BroadcastQueue mBgBroadcastQueue;
385    // Convenient for easy iteration over the queues. Foreground is first
386    // so that dispatch of foreground broadcasts gets precedence.
387    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
388
389    BroadcastQueue broadcastQueueForIntent(Intent intent) {
390        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
391        if (DEBUG_BACKGROUND_BROADCAST) {
392            Slog.i(TAG, "Broadcast intent " + intent + " on "
393                    + (isFg ? "foreground" : "background")
394                    + " queue");
395        }
396        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
397    }
398
399    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
400        for (BroadcastQueue queue : mBroadcastQueues) {
401            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
402            if (r != null) {
403                return r;
404            }
405        }
406        return null;
407    }
408
409    /**
410     * Activity we have told the window manager to have key focus.
411     */
412    ActivityRecord mFocusedActivity = null;
413
414    /**
415     * List of intents that were used to start the most recent tasks.
416     */
417    ArrayList<TaskRecord> mRecentTasks;
418    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
419
420    /**
421     * For addAppTask: cached of the last activity component that was added.
422     */
423    ComponentName mLastAddedTaskComponent;
424
425    /**
426     * For addAppTask: cached of the last activity uid that was added.
427     */
428    int mLastAddedTaskUid;
429
430    /**
431     * For addAppTask: cached of the last ActivityInfo that was added.
432     */
433    ActivityInfo mLastAddedTaskActivity;
434
435    public class PendingAssistExtras extends Binder implements Runnable {
436        public final ActivityRecord activity;
437        public final Bundle extras;
438        public final Intent intent;
439        public final String hint;
440        public final int userHandle;
441        public boolean haveResult = false;
442        public Bundle result = null;
443        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
444                String _hint, int _userHandle) {
445            activity = _activity;
446            extras = _extras;
447            intent = _intent;
448            hint = _hint;
449            userHandle = _userHandle;
450        }
451        @Override
452        public void run() {
453            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
454            synchronized (this) {
455                haveResult = true;
456                notifyAll();
457            }
458        }
459    }
460
461    final ArrayList<PendingAssistExtras> mPendingAssistExtras
462            = new ArrayList<PendingAssistExtras>();
463
464    /**
465     * Process management.
466     */
467    final ProcessList mProcessList = new ProcessList();
468
469    /**
470     * All of the applications we currently have running organized by name.
471     * The keys are strings of the application package name (as
472     * returned by the package manager), and the keys are ApplicationRecord
473     * objects.
474     */
475    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
476
477    /**
478     * Tracking long-term execution of processes to look for abuse and other
479     * bad app behavior.
480     */
481    final ProcessStatsService mProcessStats;
482
483    /**
484     * The currently running isolated processes.
485     */
486    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
487
488    /**
489     * Counter for assigning isolated process uids, to avoid frequently reusing the
490     * same ones.
491     */
492    int mNextIsolatedProcessUid = 0;
493
494    /**
495     * The currently running heavy-weight process, if any.
496     */
497    ProcessRecord mHeavyWeightProcess = null;
498
499    /**
500     * The last time that various processes have crashed.
501     */
502    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
503
504    /**
505     * Information about a process that is currently marked as bad.
506     */
507    static final class BadProcessInfo {
508        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
509            this.time = time;
510            this.shortMsg = shortMsg;
511            this.longMsg = longMsg;
512            this.stack = stack;
513        }
514
515        final long time;
516        final String shortMsg;
517        final String longMsg;
518        final String stack;
519    }
520
521    /**
522     * Set of applications that we consider to be bad, and will reject
523     * incoming broadcasts from (which the user has no control over).
524     * Processes are added to this set when they have crashed twice within
525     * a minimum amount of time; they are removed from it when they are
526     * later restarted (hopefully due to some user action).  The value is the
527     * time it was added to the list.
528     */
529    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
530
531    /**
532     * All of the processes we currently have running organized by pid.
533     * The keys are the pid running the application.
534     *
535     * <p>NOTE: This object is protected by its own lock, NOT the global
536     * activity manager lock!
537     */
538    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
539
540    /**
541     * All of the processes that have been forced to be foreground.  The key
542     * is the pid of the caller who requested it (we hold a death
543     * link on it).
544     */
545    abstract class ForegroundToken implements IBinder.DeathRecipient {
546        int pid;
547        IBinder token;
548    }
549    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
550
551    /**
552     * List of records for processes that someone had tried to start before the
553     * system was ready.  We don't start them at that point, but ensure they
554     * are started by the time booting is complete.
555     */
556    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
557
558    /**
559     * List of persistent applications that are in the process
560     * of being started.
561     */
562    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
563
564    /**
565     * Processes that are being forcibly torn down.
566     */
567    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
568
569    /**
570     * List of running applications, sorted by recent usage.
571     * The first entry in the list is the least recently used.
572     */
573    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
574
575    /**
576     * Where in mLruProcesses that the processes hosting activities start.
577     */
578    int mLruProcessActivityStart = 0;
579
580    /**
581     * Where in mLruProcesses that the processes hosting services start.
582     * This is after (lower index) than mLruProcessesActivityStart.
583     */
584    int mLruProcessServiceStart = 0;
585
586    /**
587     * List of processes that should gc as soon as things are idle.
588     */
589    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
590
591    /**
592     * Processes we want to collect PSS data from.
593     */
594    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
595
596    /**
597     * Last time we requested PSS data of all processes.
598     */
599    long mLastFullPssTime = SystemClock.uptimeMillis();
600
601    /**
602     * If set, the next time we collect PSS data we should do a full collection
603     * with data from native processes and the kernel.
604     */
605    boolean mFullPssPending = false;
606
607    /**
608     * This is the process holding what we currently consider to be
609     * the "home" activity.
610     */
611    ProcessRecord mHomeProcess;
612
613    /**
614     * This is the process holding the activity the user last visited that
615     * is in a different process from the one they are currently in.
616     */
617    ProcessRecord mPreviousProcess;
618
619    /**
620     * The time at which the previous process was last visible.
621     */
622    long mPreviousProcessVisibleTime;
623
624    /**
625     * Which uses have been started, so are allowed to run code.
626     */
627    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
628
629    /**
630     * LRU list of history of current users.  Most recently current is at the end.
631     */
632    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
633
634    /**
635     * Constant array of the users that are currently started.
636     */
637    int[] mStartedUserArray = new int[] { 0 };
638
639    /**
640     * Registered observers of the user switching mechanics.
641     */
642    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
643            = new RemoteCallbackList<IUserSwitchObserver>();
644
645    /**
646     * Currently active user switch.
647     */
648    Object mCurUserSwitchCallback;
649
650    /**
651     * Packages that the user has asked to have run in screen size
652     * compatibility mode instead of filling the screen.
653     */
654    final CompatModePackages mCompatModePackages;
655
656    /**
657     * Set of IntentSenderRecord objects that are currently active.
658     */
659    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
660            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
661
662    /**
663     * Fingerprints (hashCode()) of stack traces that we've
664     * already logged DropBox entries for.  Guarded by itself.  If
665     * something (rogue user app) forces this over
666     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
667     */
668    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
669    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
670
671    /**
672     * Strict Mode background batched logging state.
673     *
674     * The string buffer is guarded by itself, and its lock is also
675     * used to determine if another batched write is already
676     * in-flight.
677     */
678    private final StringBuilder mStrictModeBuffer = new StringBuilder();
679
680    /**
681     * Keeps track of all IIntentReceivers that have been registered for
682     * broadcasts.  Hash keys are the receiver IBinder, hash value is
683     * a ReceiverList.
684     */
685    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
686            new HashMap<IBinder, ReceiverList>();
687
688    /**
689     * Resolver for broadcast intents to registered receivers.
690     * Holds BroadcastFilter (subclass of IntentFilter).
691     */
692    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
693            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
694        @Override
695        protected boolean allowFilterResult(
696                BroadcastFilter filter, List<BroadcastFilter> dest) {
697            IBinder target = filter.receiverList.receiver.asBinder();
698            for (int i=dest.size()-1; i>=0; i--) {
699                if (dest.get(i).receiverList.receiver.asBinder() == target) {
700                    return false;
701                }
702            }
703            return true;
704        }
705
706        @Override
707        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
708            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
709                    || userId == filter.owningUserId) {
710                return super.newResult(filter, match, userId);
711            }
712            return null;
713        }
714
715        @Override
716        protected BroadcastFilter[] newArray(int size) {
717            return new BroadcastFilter[size];
718        }
719
720        @Override
721        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
722            return packageName.equals(filter.packageName);
723        }
724    };
725
726    /**
727     * State of all active sticky broadcasts per user.  Keys are the action of the
728     * sticky Intent, values are an ArrayList of all broadcasted intents with
729     * that action (which should usually be one).  The SparseArray is keyed
730     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
731     * for stickies that are sent to all users.
732     */
733    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
734            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
735
736    final ActiveServices mServices;
737
738    /**
739     * Backup/restore process management
740     */
741    String mBackupAppName = null;
742    BackupRecord mBackupTarget = null;
743
744    final ProviderMap mProviderMap;
745
746    /**
747     * List of content providers who have clients waiting for them.  The
748     * application is currently being launched and the provider will be
749     * removed from this list once it is published.
750     */
751    final ArrayList<ContentProviderRecord> mLaunchingProviders
752            = new ArrayList<ContentProviderRecord>();
753
754    /**
755     * File storing persisted {@link #mGrantedUriPermissions}.
756     */
757    private final AtomicFile mGrantFile;
758
759    /** XML constants used in {@link #mGrantFile} */
760    private static final String TAG_URI_GRANTS = "uri-grants";
761    private static final String TAG_URI_GRANT = "uri-grant";
762    private static final String ATTR_USER_HANDLE = "userHandle";
763    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
764    private static final String ATTR_TARGET_USER_ID = "targetUserId";
765    private static final String ATTR_SOURCE_PKG = "sourcePkg";
766    private static final String ATTR_TARGET_PKG = "targetPkg";
767    private static final String ATTR_URI = "uri";
768    private static final String ATTR_MODE_FLAGS = "modeFlags";
769    private static final String ATTR_CREATED_TIME = "createdTime";
770    private static final String ATTR_PREFIX = "prefix";
771
772    /**
773     * Global set of specific {@link Uri} permissions that have been granted.
774     * This optimized lookup structure maps from {@link UriPermission#targetUid}
775     * to {@link UriPermission#uri} to {@link UriPermission}.
776     */
777    @GuardedBy("this")
778    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
779            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
780
781    public static class GrantUri {
782        public final int sourceUserId;
783        public final Uri uri;
784        public boolean prefix;
785
786        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
787            this.sourceUserId = sourceUserId;
788            this.uri = uri;
789            this.prefix = prefix;
790        }
791
792        @Override
793        public int hashCode() {
794            return toString().hashCode();
795        }
796
797        @Override
798        public boolean equals(Object o) {
799            if (o instanceof GrantUri) {
800                GrantUri other = (GrantUri) o;
801                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
802                        && prefix == other.prefix;
803            }
804            return false;
805        }
806
807        @Override
808        public String toString() {
809            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
810            if (prefix) result += " [prefix]";
811            return result;
812        }
813
814        public String toSafeString() {
815            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
816            if (prefix) result += " [prefix]";
817            return result;
818        }
819
820        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
821            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
822                    ContentProvider.getUriWithoutUserId(uri), false);
823        }
824    }
825
826    CoreSettingsObserver mCoreSettingsObserver;
827
828    /**
829     * Thread-local storage used to carry caller permissions over through
830     * indirect content-provider access.
831     */
832    private class Identity {
833        public int pid;
834        public int uid;
835
836        Identity(int _pid, int _uid) {
837            pid = _pid;
838            uid = _uid;
839        }
840    }
841
842    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
843
844    /**
845     * All information we have collected about the runtime performance of
846     * any user id that can impact battery performance.
847     */
848    final BatteryStatsService mBatteryStatsService;
849
850    /**
851     * Information about component usage
852     */
853    UsageStatsManagerInternal mUsageStatsService;
854
855    /**
856     * Information about and control over application operations
857     */
858    final AppOpsService mAppOpsService;
859
860    /**
861     * Save recent tasks information across reboots.
862     */
863    final TaskPersister mTaskPersister;
864
865    /**
866     * Current configuration information.  HistoryRecord objects are given
867     * a reference to this object to indicate which configuration they are
868     * currently running in, so this object must be kept immutable.
869     */
870    Configuration mConfiguration = new Configuration();
871
872    /**
873     * Current sequencing integer of the configuration, for skipping old
874     * configurations.
875     */
876    int mConfigurationSeq = 0;
877
878    /**
879     * Hardware-reported OpenGLES version.
880     */
881    final int GL_ES_VERSION;
882
883    /**
884     * List of initialization arguments to pass to all processes when binding applications to them.
885     * For example, references to the commonly used services.
886     */
887    HashMap<String, IBinder> mAppBindArgs;
888
889    /**
890     * Temporary to avoid allocations.  Protected by main lock.
891     */
892    final StringBuilder mStringBuilder = new StringBuilder(256);
893
894    /**
895     * Used to control how we initialize the service.
896     */
897    ComponentName mTopComponent;
898    String mTopAction = Intent.ACTION_MAIN;
899    String mTopData;
900    boolean mProcessesReady = false;
901    boolean mSystemReady = false;
902    boolean mBooting = false;
903    boolean mCallFinishBooting = false;
904    boolean mBootAnimationComplete = false;
905    boolean mWaitingUpdate = false;
906    boolean mDidUpdate = false;
907    boolean mOnBattery = false;
908    boolean mLaunchWarningShown = false;
909
910    Context mContext;
911
912    int mFactoryTest;
913
914    boolean mCheckedForSetup;
915
916    /**
917     * The time at which we will allow normal application switches again,
918     * after a call to {@link #stopAppSwitches()}.
919     */
920    long mAppSwitchesAllowedTime;
921
922    /**
923     * This is set to true after the first switch after mAppSwitchesAllowedTime
924     * is set; any switches after that will clear the time.
925     */
926    boolean mDidAppSwitch;
927
928    /**
929     * Last time (in realtime) at which we checked for power usage.
930     */
931    long mLastPowerCheckRealtime;
932
933    /**
934     * Last time (in uptime) at which we checked for power usage.
935     */
936    long mLastPowerCheckUptime;
937
938    /**
939     * Set while we are wanting to sleep, to prevent any
940     * activities from being started/resumed.
941     */
942    private boolean mSleeping = false;
943
944    /**
945     * Set while we are running a voice interaction.  This overrides
946     * sleeping while it is active.
947     */
948    private boolean mRunningVoice = false;
949
950    /**
951     * State of external calls telling us if the device is asleep.
952     */
953    private boolean mWentToSleep = false;
954
955    /**
956     * State of external call telling us if the lock screen is shown.
957     */
958    private boolean mLockScreenShown = false;
959
960    /**
961     * Set if we are shutting down the system, similar to sleeping.
962     */
963    boolean mShuttingDown = false;
964
965    /**
966     * Current sequence id for oom_adj computation traversal.
967     */
968    int mAdjSeq = 0;
969
970    /**
971     * Current sequence id for process LRU updating.
972     */
973    int mLruSeq = 0;
974
975    /**
976     * Keep track of the non-cached/empty process we last found, to help
977     * determine how to distribute cached/empty processes next time.
978     */
979    int mNumNonCachedProcs = 0;
980
981    /**
982     * Keep track of the number of cached hidden procs, to balance oom adj
983     * distribution between those and empty procs.
984     */
985    int mNumCachedHiddenProcs = 0;
986
987    /**
988     * Keep track of the number of service processes we last found, to
989     * determine on the next iteration which should be B services.
990     */
991    int mNumServiceProcs = 0;
992    int mNewNumAServiceProcs = 0;
993    int mNewNumServiceProcs = 0;
994
995    /**
996     * Allow the current computed overall memory level of the system to go down?
997     * This is set to false when we are killing processes for reasons other than
998     * memory management, so that the now smaller process list will not be taken as
999     * an indication that memory is tighter.
1000     */
1001    boolean mAllowLowerMemLevel = false;
1002
1003    /**
1004     * The last computed memory level, for holding when we are in a state that
1005     * processes are going away for other reasons.
1006     */
1007    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1008
1009    /**
1010     * The last total number of process we have, to determine if changes actually look
1011     * like a shrinking number of process due to lower RAM.
1012     */
1013    int mLastNumProcesses;
1014
1015    /**
1016     * The uptime of the last time we performed idle maintenance.
1017     */
1018    long mLastIdleTime = SystemClock.uptimeMillis();
1019
1020    /**
1021     * Total time spent with RAM that has been added in the past since the last idle time.
1022     */
1023    long mLowRamTimeSinceLastIdle = 0;
1024
1025    /**
1026     * If RAM is currently low, when that horrible situation started.
1027     */
1028    long mLowRamStartTime = 0;
1029
1030    /**
1031     * For reporting to battery stats the current top application.
1032     */
1033    private String mCurResumedPackage = null;
1034    private int mCurResumedUid = -1;
1035
1036    /**
1037     * For reporting to battery stats the apps currently running foreground
1038     * service.  The ProcessMap is package/uid tuples; each of these contain
1039     * an array of the currently foreground processes.
1040     */
1041    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1042            = new ProcessMap<ArrayList<ProcessRecord>>();
1043
1044    /**
1045     * This is set if we had to do a delayed dexopt of an app before launching
1046     * it, to increase the ANR timeouts in that case.
1047     */
1048    boolean mDidDexOpt;
1049
1050    /**
1051     * Set if the systemServer made a call to enterSafeMode.
1052     */
1053    boolean mSafeMode;
1054
1055    String mDebugApp = null;
1056    boolean mWaitForDebugger = false;
1057    boolean mDebugTransient = false;
1058    String mOrigDebugApp = null;
1059    boolean mOrigWaitForDebugger = false;
1060    boolean mAlwaysFinishActivities = false;
1061    IActivityController mController = null;
1062    String mProfileApp = null;
1063    ProcessRecord mProfileProc = null;
1064    String mProfileFile;
1065    ParcelFileDescriptor mProfileFd;
1066    int mSamplingInterval = 0;
1067    boolean mAutoStopProfiler = false;
1068    int mProfileType = 0;
1069    String mOpenGlTraceApp = null;
1070
1071    static class ProcessChangeItem {
1072        static final int CHANGE_ACTIVITIES = 1<<0;
1073        static final int CHANGE_PROCESS_STATE = 1<<1;
1074        int changes;
1075        int uid;
1076        int pid;
1077        int processState;
1078        boolean foregroundActivities;
1079    }
1080
1081    final RemoteCallbackList<IProcessObserver> mProcessObservers
1082            = new RemoteCallbackList<IProcessObserver>();
1083    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1084
1085    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1086            = new ArrayList<ProcessChangeItem>();
1087    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1088            = new ArrayList<ProcessChangeItem>();
1089
1090    /**
1091     * Runtime CPU use collection thread.  This object's lock is used to
1092     * perform synchronization with the thread (notifying it to run).
1093     */
1094    final Thread mProcessCpuThread;
1095
1096    /**
1097     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1098     * Must acquire this object's lock when accessing it.
1099     * NOTE: this lock will be held while doing long operations (trawling
1100     * through all processes in /proc), so it should never be acquired by
1101     * any critical paths such as when holding the main activity manager lock.
1102     */
1103    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1104            MONITOR_THREAD_CPU_USAGE);
1105    final AtomicLong mLastCpuTime = new AtomicLong(0);
1106    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1107
1108    long mLastWriteTime = 0;
1109
1110    /**
1111     * Used to retain an update lock when the foreground activity is in
1112     * immersive mode.
1113     */
1114    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1115
1116    /**
1117     * Set to true after the system has finished booting.
1118     */
1119    boolean mBooted = false;
1120
1121    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1122    int mProcessLimitOverride = -1;
1123
1124    WindowManagerService mWindowManager;
1125
1126    final ActivityThread mSystemThread;
1127
1128    // Holds the current foreground user's id
1129    int mCurrentUserId = 0;
1130    // Holds the target user's id during a user switch
1131    int mTargetUserId = UserHandle.USER_NULL;
1132    // If there are multiple profiles for the current user, their ids are here
1133    // Currently only the primary user can have managed profiles
1134    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1135
1136    /**
1137     * Mapping from each known user ID to the profile group ID it is associated with.
1138     */
1139    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1140
1141    private UserManagerService mUserManager;
1142
1143    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1144        final ProcessRecord mApp;
1145        final int mPid;
1146        final IApplicationThread mAppThread;
1147
1148        AppDeathRecipient(ProcessRecord app, int pid,
1149                IApplicationThread thread) {
1150            if (localLOGV) Slog.v(
1151                TAG, "New death recipient " + this
1152                + " for thread " + thread.asBinder());
1153            mApp = app;
1154            mPid = pid;
1155            mAppThread = thread;
1156        }
1157
1158        @Override
1159        public void binderDied() {
1160            if (localLOGV) Slog.v(
1161                TAG, "Death received in " + this
1162                + " for thread " + mAppThread.asBinder());
1163            synchronized(ActivityManagerService.this) {
1164                appDiedLocked(mApp, mPid, mAppThread);
1165            }
1166        }
1167    }
1168
1169    static final int SHOW_ERROR_MSG = 1;
1170    static final int SHOW_NOT_RESPONDING_MSG = 2;
1171    static final int SHOW_FACTORY_ERROR_MSG = 3;
1172    static final int UPDATE_CONFIGURATION_MSG = 4;
1173    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1174    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1175    static final int SERVICE_TIMEOUT_MSG = 12;
1176    static final int UPDATE_TIME_ZONE = 13;
1177    static final int SHOW_UID_ERROR_MSG = 14;
1178    static final int IM_FEELING_LUCKY_MSG = 15;
1179    static final int PROC_START_TIMEOUT_MSG = 20;
1180    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1181    static final int KILL_APPLICATION_MSG = 22;
1182    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1183    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1184    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1185    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1186    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1187    static final int CLEAR_DNS_CACHE_MSG = 28;
1188    static final int UPDATE_HTTP_PROXY_MSG = 29;
1189    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1190    static final int DISPATCH_PROCESSES_CHANGED = 31;
1191    static final int DISPATCH_PROCESS_DIED = 32;
1192    static final int REPORT_MEM_USAGE_MSG = 33;
1193    static final int REPORT_USER_SWITCH_MSG = 34;
1194    static final int CONTINUE_USER_SWITCH_MSG = 35;
1195    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1196    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1197    static final int PERSIST_URI_GRANTS_MSG = 38;
1198    static final int REQUEST_ALL_PSS_MSG = 39;
1199    static final int START_PROFILES_MSG = 40;
1200    static final int UPDATE_TIME = 41;
1201    static final int SYSTEM_USER_START_MSG = 42;
1202    static final int SYSTEM_USER_CURRENT_MSG = 43;
1203    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1204    static final int FINISH_BOOTING_MSG = 45;
1205    static final int START_USER_SWITCH_MSG = 46;
1206    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1207
1208    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1209    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1210    static final int FIRST_COMPAT_MODE_MSG = 300;
1211    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1212
1213    AlertDialog mUidAlert;
1214    CompatModeDialog mCompatModeDialog;
1215    long mLastMemUsageReportTime = 0;
1216
1217    private LockToAppRequestDialog mLockToAppRequest;
1218
1219    /**
1220     * Flag whether the current user is a "monkey", i.e. whether
1221     * the UI is driven by a UI automation tool.
1222     */
1223    private boolean mUserIsMonkey;
1224
1225    /** Flag whether the device has a Recents UI */
1226    boolean mHasRecents;
1227
1228    /** The dimensions of the thumbnails in the Recents UI. */
1229    int mThumbnailWidth;
1230    int mThumbnailHeight;
1231
1232    final ServiceThread mHandlerThread;
1233    final MainHandler mHandler;
1234
1235    final class MainHandler extends Handler {
1236        public MainHandler(Looper looper) {
1237            super(looper, null, true);
1238        }
1239
1240        @Override
1241        public void handleMessage(Message msg) {
1242            switch (msg.what) {
1243            case SHOW_ERROR_MSG: {
1244                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1245                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1246                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1247                synchronized (ActivityManagerService.this) {
1248                    ProcessRecord proc = (ProcessRecord)data.get("app");
1249                    AppErrorResult res = (AppErrorResult) data.get("result");
1250                    if (proc != null && proc.crashDialog != null) {
1251                        Slog.e(TAG, "App already has crash dialog: " + proc);
1252                        if (res != null) {
1253                            res.set(0);
1254                        }
1255                        return;
1256                    }
1257                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1258                            >= Process.FIRST_APPLICATION_UID
1259                            && proc.pid != MY_PID);
1260                    for (int userId : mCurrentProfileIds) {
1261                        isBackground &= (proc.userId != userId);
1262                    }
1263                    if (isBackground && !showBackground) {
1264                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1265                        if (res != null) {
1266                            res.set(0);
1267                        }
1268                        return;
1269                    }
1270                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1271                        Dialog d = new AppErrorDialog(mContext,
1272                                ActivityManagerService.this, res, proc);
1273                        d.show();
1274                        proc.crashDialog = d;
1275                    } else {
1276                        // The device is asleep, so just pretend that the user
1277                        // saw a crash dialog and hit "force quit".
1278                        if (res != null) {
1279                            res.set(0);
1280                        }
1281                    }
1282                }
1283
1284                ensureBootCompleted();
1285            } break;
1286            case SHOW_NOT_RESPONDING_MSG: {
1287                synchronized (ActivityManagerService.this) {
1288                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1289                    ProcessRecord proc = (ProcessRecord)data.get("app");
1290                    if (proc != null && proc.anrDialog != null) {
1291                        Slog.e(TAG, "App already has anr dialog: " + proc);
1292                        return;
1293                    }
1294
1295                    Intent intent = new Intent("android.intent.action.ANR");
1296                    if (!mProcessesReady) {
1297                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1298                                | Intent.FLAG_RECEIVER_FOREGROUND);
1299                    }
1300                    broadcastIntentLocked(null, null, intent,
1301                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1302                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1303
1304                    if (mShowDialogs) {
1305                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1306                                mContext, proc, (ActivityRecord)data.get("activity"),
1307                                msg.arg1 != 0);
1308                        d.show();
1309                        proc.anrDialog = d;
1310                    } else {
1311                        // Just kill the app if there is no dialog to be shown.
1312                        killAppAtUsersRequest(proc, null);
1313                    }
1314                }
1315
1316                ensureBootCompleted();
1317            } break;
1318            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1319                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1320                synchronized (ActivityManagerService.this) {
1321                    ProcessRecord proc = (ProcessRecord) data.get("app");
1322                    if (proc == null) {
1323                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1324                        break;
1325                    }
1326                    if (proc.crashDialog != null) {
1327                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1328                        return;
1329                    }
1330                    AppErrorResult res = (AppErrorResult) data.get("result");
1331                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1332                        Dialog d = new StrictModeViolationDialog(mContext,
1333                                ActivityManagerService.this, res, proc);
1334                        d.show();
1335                        proc.crashDialog = d;
1336                    } else {
1337                        // The device is asleep, so just pretend that the user
1338                        // saw a crash dialog and hit "force quit".
1339                        res.set(0);
1340                    }
1341                }
1342                ensureBootCompleted();
1343            } break;
1344            case SHOW_FACTORY_ERROR_MSG: {
1345                Dialog d = new FactoryErrorDialog(
1346                    mContext, msg.getData().getCharSequence("msg"));
1347                d.show();
1348                ensureBootCompleted();
1349            } break;
1350            case UPDATE_CONFIGURATION_MSG: {
1351                final ContentResolver resolver = mContext.getContentResolver();
1352                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1353            } break;
1354            case GC_BACKGROUND_PROCESSES_MSG: {
1355                synchronized (ActivityManagerService.this) {
1356                    performAppGcsIfAppropriateLocked();
1357                }
1358            } break;
1359            case WAIT_FOR_DEBUGGER_MSG: {
1360                synchronized (ActivityManagerService.this) {
1361                    ProcessRecord app = (ProcessRecord)msg.obj;
1362                    if (msg.arg1 != 0) {
1363                        if (!app.waitedForDebugger) {
1364                            Dialog d = new AppWaitingForDebuggerDialog(
1365                                    ActivityManagerService.this,
1366                                    mContext, app);
1367                            app.waitDialog = d;
1368                            app.waitedForDebugger = true;
1369                            d.show();
1370                        }
1371                    } else {
1372                        if (app.waitDialog != null) {
1373                            app.waitDialog.dismiss();
1374                            app.waitDialog = null;
1375                        }
1376                    }
1377                }
1378            } break;
1379            case SERVICE_TIMEOUT_MSG: {
1380                if (mDidDexOpt) {
1381                    mDidDexOpt = false;
1382                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1383                    nmsg.obj = msg.obj;
1384                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1385                    return;
1386                }
1387                mServices.serviceTimeout((ProcessRecord)msg.obj);
1388            } break;
1389            case UPDATE_TIME_ZONE: {
1390                synchronized (ActivityManagerService.this) {
1391                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1392                        ProcessRecord r = mLruProcesses.get(i);
1393                        if (r.thread != null) {
1394                            try {
1395                                r.thread.updateTimeZone();
1396                            } catch (RemoteException ex) {
1397                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1398                            }
1399                        }
1400                    }
1401                }
1402            } break;
1403            case CLEAR_DNS_CACHE_MSG: {
1404                synchronized (ActivityManagerService.this) {
1405                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1406                        ProcessRecord r = mLruProcesses.get(i);
1407                        if (r.thread != null) {
1408                            try {
1409                                r.thread.clearDnsCache();
1410                            } catch (RemoteException ex) {
1411                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1412                            }
1413                        }
1414                    }
1415                }
1416            } break;
1417            case UPDATE_HTTP_PROXY_MSG: {
1418                ProxyInfo proxy = (ProxyInfo)msg.obj;
1419                String host = "";
1420                String port = "";
1421                String exclList = "";
1422                Uri pacFileUrl = Uri.EMPTY;
1423                if (proxy != null) {
1424                    host = proxy.getHost();
1425                    port = Integer.toString(proxy.getPort());
1426                    exclList = proxy.getExclusionListAsString();
1427                    pacFileUrl = proxy.getPacFileUrl();
1428                }
1429                synchronized (ActivityManagerService.this) {
1430                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1431                        ProcessRecord r = mLruProcesses.get(i);
1432                        if (r.thread != null) {
1433                            try {
1434                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1435                            } catch (RemoteException ex) {
1436                                Slog.w(TAG, "Failed to update http proxy for: " +
1437                                        r.info.processName);
1438                            }
1439                        }
1440                    }
1441                }
1442            } break;
1443            case SHOW_UID_ERROR_MSG: {
1444                String title = "System UIDs Inconsistent";
1445                String text = "UIDs on the system are inconsistent, you need to wipe your"
1446                        + " data partition or your device will be unstable.";
1447                Log.e(TAG, title + ": " + text);
1448                if (mShowDialogs) {
1449                    // XXX This is a temporary dialog, no need to localize.
1450                    AlertDialog d = new BaseErrorDialog(mContext);
1451                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1452                    d.setCancelable(false);
1453                    d.setTitle(title);
1454                    d.setMessage(text);
1455                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1456                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1457                    mUidAlert = d;
1458                    d.show();
1459                }
1460            } break;
1461            case IM_FEELING_LUCKY_MSG: {
1462                if (mUidAlert != null) {
1463                    mUidAlert.dismiss();
1464                    mUidAlert = null;
1465                }
1466            } break;
1467            case PROC_START_TIMEOUT_MSG: {
1468                if (mDidDexOpt) {
1469                    mDidDexOpt = false;
1470                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1471                    nmsg.obj = msg.obj;
1472                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1473                    return;
1474                }
1475                ProcessRecord app = (ProcessRecord)msg.obj;
1476                synchronized (ActivityManagerService.this) {
1477                    processStartTimedOutLocked(app);
1478                }
1479            } break;
1480            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1481                synchronized (ActivityManagerService.this) {
1482                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1483                }
1484            } break;
1485            case KILL_APPLICATION_MSG: {
1486                synchronized (ActivityManagerService.this) {
1487                    int appid = msg.arg1;
1488                    boolean restart = (msg.arg2 == 1);
1489                    Bundle bundle = (Bundle)msg.obj;
1490                    String pkg = bundle.getString("pkg");
1491                    String reason = bundle.getString("reason");
1492                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1493                            false, UserHandle.USER_ALL, reason);
1494                }
1495            } break;
1496            case FINALIZE_PENDING_INTENT_MSG: {
1497                ((PendingIntentRecord)msg.obj).completeFinalize();
1498            } break;
1499            case POST_HEAVY_NOTIFICATION_MSG: {
1500                INotificationManager inm = NotificationManager.getService();
1501                if (inm == null) {
1502                    return;
1503                }
1504
1505                ActivityRecord root = (ActivityRecord)msg.obj;
1506                ProcessRecord process = root.app;
1507                if (process == null) {
1508                    return;
1509                }
1510
1511                try {
1512                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1513                    String text = mContext.getString(R.string.heavy_weight_notification,
1514                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1515                    Notification notification = new Notification();
1516                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1517                    notification.when = 0;
1518                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1519                    notification.tickerText = text;
1520                    notification.defaults = 0; // please be quiet
1521                    notification.sound = null;
1522                    notification.vibrate = null;
1523                    notification.color = mContext.getResources().getColor(
1524                            com.android.internal.R.color.system_notification_accent_color);
1525                    notification.setLatestEventInfo(context, text,
1526                            mContext.getText(R.string.heavy_weight_notification_detail),
1527                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1528                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1529                                    new UserHandle(root.userId)));
1530
1531                    try {
1532                        int[] outId = new int[1];
1533                        inm.enqueueNotificationWithTag("android", "android", null,
1534                                R.string.heavy_weight_notification,
1535                                notification, outId, root.userId);
1536                    } catch (RuntimeException e) {
1537                        Slog.w(ActivityManagerService.TAG,
1538                                "Error showing notification for heavy-weight app", e);
1539                    } catch (RemoteException e) {
1540                    }
1541                } catch (NameNotFoundException e) {
1542                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1543                }
1544            } break;
1545            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1546                INotificationManager inm = NotificationManager.getService();
1547                if (inm == null) {
1548                    return;
1549                }
1550                try {
1551                    inm.cancelNotificationWithTag("android", null,
1552                            R.string.heavy_weight_notification,  msg.arg1);
1553                } catch (RuntimeException e) {
1554                    Slog.w(ActivityManagerService.TAG,
1555                            "Error canceling notification for service", e);
1556                } catch (RemoteException e) {
1557                }
1558            } break;
1559            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1560                synchronized (ActivityManagerService.this) {
1561                    checkExcessivePowerUsageLocked(true);
1562                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1563                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1564                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1565                }
1566            } break;
1567            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1568                synchronized (ActivityManagerService.this) {
1569                    ActivityRecord ar = (ActivityRecord)msg.obj;
1570                    if (mCompatModeDialog != null) {
1571                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1572                                ar.info.applicationInfo.packageName)) {
1573                            return;
1574                        }
1575                        mCompatModeDialog.dismiss();
1576                        mCompatModeDialog = null;
1577                    }
1578                    if (ar != null && false) {
1579                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1580                                ar.packageName)) {
1581                            int mode = mCompatModePackages.computeCompatModeLocked(
1582                                    ar.info.applicationInfo);
1583                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1584                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1585                                mCompatModeDialog = new CompatModeDialog(
1586                                        ActivityManagerService.this, mContext,
1587                                        ar.info.applicationInfo);
1588                                mCompatModeDialog.show();
1589                            }
1590                        }
1591                    }
1592                }
1593                break;
1594            }
1595            case DISPATCH_PROCESSES_CHANGED: {
1596                dispatchProcessesChanged();
1597                break;
1598            }
1599            case DISPATCH_PROCESS_DIED: {
1600                final int pid = msg.arg1;
1601                final int uid = msg.arg2;
1602                dispatchProcessDied(pid, uid);
1603                break;
1604            }
1605            case REPORT_MEM_USAGE_MSG: {
1606                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1607                Thread thread = new Thread() {
1608                    @Override public void run() {
1609                        final SparseArray<ProcessMemInfo> infoMap
1610                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1611                        for (int i=0, N=memInfos.size(); i<N; i++) {
1612                            ProcessMemInfo mi = memInfos.get(i);
1613                            infoMap.put(mi.pid, mi);
1614                        }
1615                        updateCpuStatsNow();
1616                        synchronized (mProcessCpuTracker) {
1617                            final int N = mProcessCpuTracker.countStats();
1618                            for (int i=0; i<N; i++) {
1619                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1620                                if (st.vsize > 0) {
1621                                    long pss = Debug.getPss(st.pid, null);
1622                                    if (pss > 0) {
1623                                        if (infoMap.indexOfKey(st.pid) < 0) {
1624                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1625                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1626                                            mi.pss = pss;
1627                                            memInfos.add(mi);
1628                                        }
1629                                    }
1630                                }
1631                            }
1632                        }
1633
1634                        long totalPss = 0;
1635                        for (int i=0, N=memInfos.size(); i<N; i++) {
1636                            ProcessMemInfo mi = memInfos.get(i);
1637                            if (mi.pss == 0) {
1638                                mi.pss = Debug.getPss(mi.pid, null);
1639                            }
1640                            totalPss += mi.pss;
1641                        }
1642                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1643                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1644                                if (lhs.oomAdj != rhs.oomAdj) {
1645                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1646                                }
1647                                if (lhs.pss != rhs.pss) {
1648                                    return lhs.pss < rhs.pss ? 1 : -1;
1649                                }
1650                                return 0;
1651                            }
1652                        });
1653
1654                        StringBuilder tag = new StringBuilder(128);
1655                        StringBuilder stack = new StringBuilder(128);
1656                        tag.append("Low on memory -- ");
1657                        appendMemBucket(tag, totalPss, "total", false);
1658                        appendMemBucket(stack, totalPss, "total", true);
1659
1660                        StringBuilder logBuilder = new StringBuilder(1024);
1661                        logBuilder.append("Low on memory:\n");
1662
1663                        boolean firstLine = true;
1664                        int lastOomAdj = Integer.MIN_VALUE;
1665                        for (int i=0, N=memInfos.size(); i<N; i++) {
1666                            ProcessMemInfo mi = memInfos.get(i);
1667
1668                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1669                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1670                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1671                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1672                                if (lastOomAdj != mi.oomAdj) {
1673                                    lastOomAdj = mi.oomAdj;
1674                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1675                                        tag.append(" / ");
1676                                    }
1677                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1678                                        if (firstLine) {
1679                                            stack.append(":");
1680                                            firstLine = false;
1681                                        }
1682                                        stack.append("\n\t at ");
1683                                    } else {
1684                                        stack.append("$");
1685                                    }
1686                                } else {
1687                                    tag.append(" ");
1688                                    stack.append("$");
1689                                }
1690                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1691                                    appendMemBucket(tag, mi.pss, mi.name, false);
1692                                }
1693                                appendMemBucket(stack, mi.pss, mi.name, true);
1694                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1695                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1696                                    stack.append("(");
1697                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1698                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1699                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1700                                            stack.append(":");
1701                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1702                                        }
1703                                    }
1704                                    stack.append(")");
1705                                }
1706                            }
1707
1708                            logBuilder.append("  ");
1709                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1710                            logBuilder.append(' ');
1711                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1712                            logBuilder.append(' ');
1713                            ProcessList.appendRamKb(logBuilder, mi.pss);
1714                            logBuilder.append(" kB: ");
1715                            logBuilder.append(mi.name);
1716                            logBuilder.append(" (");
1717                            logBuilder.append(mi.pid);
1718                            logBuilder.append(") ");
1719                            logBuilder.append(mi.adjType);
1720                            logBuilder.append('\n');
1721                            if (mi.adjReason != null) {
1722                                logBuilder.append("                      ");
1723                                logBuilder.append(mi.adjReason);
1724                                logBuilder.append('\n');
1725                            }
1726                        }
1727
1728                        logBuilder.append("           ");
1729                        ProcessList.appendRamKb(logBuilder, totalPss);
1730                        logBuilder.append(" kB: TOTAL\n");
1731
1732                        long[] infos = new long[Debug.MEMINFO_COUNT];
1733                        Debug.getMemInfo(infos);
1734                        logBuilder.append("  MemInfo: ");
1735                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1736                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1737                        logBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
1738                        logBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
1739                        logBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
1740                        logBuilder.append("           ");
1741                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1742                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1743                        logBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
1744                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1745                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1746                            logBuilder.append("  ZRAM: ");
1747                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1748                            logBuilder.append(" kB RAM, ");
1749                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1750                            logBuilder.append(" kB swap total, ");
1751                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1752                            logBuilder.append(" kB swap free\n");
1753                        }
1754                        Slog.i(TAG, logBuilder.toString());
1755
1756                        StringBuilder dropBuilder = new StringBuilder(1024);
1757                        /*
1758                        StringWriter oomSw = new StringWriter();
1759                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1760                        StringWriter catSw = new StringWriter();
1761                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1762                        String[] emptyArgs = new String[] { };
1763                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1764                        oomPw.flush();
1765                        String oomString = oomSw.toString();
1766                        */
1767                        dropBuilder.append(stack);
1768                        dropBuilder.append('\n');
1769                        dropBuilder.append('\n');
1770                        dropBuilder.append(logBuilder);
1771                        dropBuilder.append('\n');
1772                        /*
1773                        dropBuilder.append(oomString);
1774                        dropBuilder.append('\n');
1775                        */
1776                        StringWriter catSw = new StringWriter();
1777                        synchronized (ActivityManagerService.this) {
1778                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1779                            String[] emptyArgs = new String[] { };
1780                            catPw.println();
1781                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1782                            catPw.println();
1783                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1784                                    false, false, null);
1785                            catPw.println();
1786                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1787                            catPw.flush();
1788                        }
1789                        dropBuilder.append(catSw.toString());
1790                        addErrorToDropBox("lowmem", null, "system_server", null,
1791                                null, tag.toString(), dropBuilder.toString(), null, null);
1792                        //Slog.i(TAG, "Sent to dropbox:");
1793                        //Slog.i(TAG, dropBuilder.toString());
1794                        synchronized (ActivityManagerService.this) {
1795                            long now = SystemClock.uptimeMillis();
1796                            if (mLastMemUsageReportTime < now) {
1797                                mLastMemUsageReportTime = now;
1798                            }
1799                        }
1800                    }
1801                };
1802                thread.start();
1803                break;
1804            }
1805            case START_USER_SWITCH_MSG: {
1806                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1807                break;
1808            }
1809            case REPORT_USER_SWITCH_MSG: {
1810                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1811                break;
1812            }
1813            case CONTINUE_USER_SWITCH_MSG: {
1814                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1815                break;
1816            }
1817            case USER_SWITCH_TIMEOUT_MSG: {
1818                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1819                break;
1820            }
1821            case IMMERSIVE_MODE_LOCK_MSG: {
1822                final boolean nextState = (msg.arg1 != 0);
1823                if (mUpdateLock.isHeld() != nextState) {
1824                    if (DEBUG_IMMERSIVE) {
1825                        final ActivityRecord r = (ActivityRecord) msg.obj;
1826                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1827                    }
1828                    if (nextState) {
1829                        mUpdateLock.acquire();
1830                    } else {
1831                        mUpdateLock.release();
1832                    }
1833                }
1834                break;
1835            }
1836            case PERSIST_URI_GRANTS_MSG: {
1837                writeGrantedUriPermissions();
1838                break;
1839            }
1840            case REQUEST_ALL_PSS_MSG: {
1841                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1842                break;
1843            }
1844            case START_PROFILES_MSG: {
1845                synchronized (ActivityManagerService.this) {
1846                    startProfilesLocked();
1847                }
1848                break;
1849            }
1850            case UPDATE_TIME: {
1851                synchronized (ActivityManagerService.this) {
1852                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1853                        ProcessRecord r = mLruProcesses.get(i);
1854                        if (r.thread != null) {
1855                            try {
1856                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1857                            } catch (RemoteException ex) {
1858                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1859                            }
1860                        }
1861                    }
1862                }
1863                break;
1864            }
1865            case SYSTEM_USER_START_MSG: {
1866                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1867                        Integer.toString(msg.arg1), msg.arg1);
1868                mSystemServiceManager.startUser(msg.arg1);
1869                break;
1870            }
1871            case SYSTEM_USER_CURRENT_MSG: {
1872                mBatteryStatsService.noteEvent(
1873                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1874                        Integer.toString(msg.arg2), msg.arg2);
1875                mBatteryStatsService.noteEvent(
1876                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1877                        Integer.toString(msg.arg1), msg.arg1);
1878                mSystemServiceManager.switchUser(msg.arg1);
1879                mLockToAppRequest.clearPrompt();
1880                break;
1881            }
1882            case ENTER_ANIMATION_COMPLETE_MSG: {
1883                synchronized (ActivityManagerService.this) {
1884                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1885                    if (r != null && r.app != null && r.app.thread != null) {
1886                        try {
1887                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1888                        } catch (RemoteException e) {
1889                        }
1890                    }
1891                }
1892                break;
1893            }
1894            case FINISH_BOOTING_MSG: {
1895                if (msg.arg1 != 0) {
1896                    finishBooting();
1897                }
1898                if (msg.arg2 != 0) {
1899                    enableScreenAfterBoot();
1900                }
1901                break;
1902            }
1903            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1904                try {
1905                    Locale l = (Locale) msg.obj;
1906                    IBinder service = ServiceManager.getService("mount");
1907                    IMountService mountService = IMountService.Stub.asInterface(service);
1908                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1909                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1910                } catch (RemoteException e) {
1911                    Log.e(TAG, "Error storing locale for decryption UI", e);
1912                }
1913                break;
1914            }
1915            }
1916        }
1917    };
1918
1919    static final int COLLECT_PSS_BG_MSG = 1;
1920
1921    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1922        @Override
1923        public void handleMessage(Message msg) {
1924            switch (msg.what) {
1925            case COLLECT_PSS_BG_MSG: {
1926                long start = SystemClock.uptimeMillis();
1927                MemInfoReader memInfo = null;
1928                synchronized (ActivityManagerService.this) {
1929                    if (mFullPssPending) {
1930                        mFullPssPending = false;
1931                        memInfo = new MemInfoReader();
1932                    }
1933                }
1934                if (memInfo != null) {
1935                    updateCpuStatsNow();
1936                    long nativeTotalPss = 0;
1937                    synchronized (mProcessCpuTracker) {
1938                        final int N = mProcessCpuTracker.countStats();
1939                        for (int j=0; j<N; j++) {
1940                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1941                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1942                                // This is definitely an application process; skip it.
1943                                continue;
1944                            }
1945                            synchronized (mPidsSelfLocked) {
1946                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1947                                    // This is one of our own processes; skip it.
1948                                    continue;
1949                                }
1950                            }
1951                            nativeTotalPss += Debug.getPss(st.pid, null);
1952                        }
1953                    }
1954                    memInfo.readMemInfo();
1955                    synchronized (ActivityManagerService.this) {
1956                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1957                                + (SystemClock.uptimeMillis()-start) + "ms");
1958                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1959                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1960                                memInfo.getKernelUsedSizeKb(), 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    private void start() {
2365        Process.removeAllProcessGroups();
2366        mProcessCpuThread.start();
2367
2368        mBatteryStatsService.publish(mContext);
2369        mAppOpsService.publish(mContext);
2370        Slog.d("AppOps", "AppOpsService published");
2371        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2372    }
2373
2374    public void initPowerManagement() {
2375        mStackSupervisor.initPowerManagement();
2376        mBatteryStatsService.initPowerManagement();
2377    }
2378
2379    @Override
2380    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2381            throws RemoteException {
2382        if (code == SYSPROPS_TRANSACTION) {
2383            // We need to tell all apps about the system property change.
2384            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2385            synchronized(this) {
2386                final int NP = mProcessNames.getMap().size();
2387                for (int ip=0; ip<NP; ip++) {
2388                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2389                    final int NA = apps.size();
2390                    for (int ia=0; ia<NA; ia++) {
2391                        ProcessRecord app = apps.valueAt(ia);
2392                        if (app.thread != null) {
2393                            procs.add(app.thread.asBinder());
2394                        }
2395                    }
2396                }
2397            }
2398
2399            int N = procs.size();
2400            for (int i=0; i<N; i++) {
2401                Parcel data2 = Parcel.obtain();
2402                try {
2403                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2404                } catch (RemoteException e) {
2405                }
2406                data2.recycle();
2407            }
2408        }
2409        try {
2410            return super.onTransact(code, data, reply, flags);
2411        } catch (RuntimeException e) {
2412            // The activity manager only throws security exceptions, so let's
2413            // log all others.
2414            if (!(e instanceof SecurityException)) {
2415                Slog.wtf(TAG, "Activity Manager Crash", e);
2416            }
2417            throw e;
2418        }
2419    }
2420
2421    void updateCpuStats() {
2422        final long now = SystemClock.uptimeMillis();
2423        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2424            return;
2425        }
2426        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2427            synchronized (mProcessCpuThread) {
2428                mProcessCpuThread.notify();
2429            }
2430        }
2431    }
2432
2433    void updateCpuStatsNow() {
2434        synchronized (mProcessCpuTracker) {
2435            mProcessCpuMutexFree.set(false);
2436            final long now = SystemClock.uptimeMillis();
2437            boolean haveNewCpuStats = false;
2438
2439            if (MONITOR_CPU_USAGE &&
2440                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2441                mLastCpuTime.set(now);
2442                haveNewCpuStats = true;
2443                mProcessCpuTracker.update();
2444                //Slog.i(TAG, mProcessCpu.printCurrentState());
2445                //Slog.i(TAG, "Total CPU usage: "
2446                //        + mProcessCpu.getTotalCpuPercent() + "%");
2447
2448                // Slog the cpu usage if the property is set.
2449                if ("true".equals(SystemProperties.get("events.cpu"))) {
2450                    int user = mProcessCpuTracker.getLastUserTime();
2451                    int system = mProcessCpuTracker.getLastSystemTime();
2452                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2453                    int irq = mProcessCpuTracker.getLastIrqTime();
2454                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2455                    int idle = mProcessCpuTracker.getLastIdleTime();
2456
2457                    int total = user + system + iowait + irq + softIrq + idle;
2458                    if (total == 0) total = 1;
2459
2460                    EventLog.writeEvent(EventLogTags.CPU,
2461                            ((user+system+iowait+irq+softIrq) * 100) / total,
2462                            (user * 100) / total,
2463                            (system * 100) / total,
2464                            (iowait * 100) / total,
2465                            (irq * 100) / total,
2466                            (softIrq * 100) / total);
2467                }
2468            }
2469
2470            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2471            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2472            synchronized(bstats) {
2473                synchronized(mPidsSelfLocked) {
2474                    if (haveNewCpuStats) {
2475                        if (mOnBattery) {
2476                            int perc = bstats.startAddingCpuLocked();
2477                            int totalUTime = 0;
2478                            int totalSTime = 0;
2479                            final int N = mProcessCpuTracker.countStats();
2480                            for (int i=0; i<N; i++) {
2481                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2482                                if (!st.working) {
2483                                    continue;
2484                                }
2485                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2486                                int otherUTime = (st.rel_utime*perc)/100;
2487                                int otherSTime = (st.rel_stime*perc)/100;
2488                                totalUTime += otherUTime;
2489                                totalSTime += otherSTime;
2490                                if (pr != null) {
2491                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2492                                    if (ps == null || !ps.isActive()) {
2493                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2494                                                pr.info.uid, pr.processName);
2495                                    }
2496                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2497                                            st.rel_stime-otherSTime);
2498                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2499                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2500                                } else {
2501                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2502                                    if (ps == null || !ps.isActive()) {
2503                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2504                                                bstats.mapUid(st.uid), st.name);
2505                                    }
2506                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2507                                            st.rel_stime-otherSTime);
2508                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2509                                }
2510                            }
2511                            bstats.finishAddingCpuLocked(perc, totalUTime,
2512                                    totalSTime, cpuSpeedTimes);
2513                        }
2514                    }
2515                }
2516
2517                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2518                    mLastWriteTime = now;
2519                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2520                }
2521            }
2522        }
2523    }
2524
2525    @Override
2526    public void batteryNeedsCpuUpdate() {
2527        updateCpuStatsNow();
2528    }
2529
2530    @Override
2531    public void batteryPowerChanged(boolean onBattery) {
2532        // When plugging in, update the CPU stats first before changing
2533        // the plug state.
2534        updateCpuStatsNow();
2535        synchronized (this) {
2536            synchronized(mPidsSelfLocked) {
2537                mOnBattery = DEBUG_POWER ? true : onBattery;
2538            }
2539        }
2540    }
2541
2542    /**
2543     * Initialize the application bind args. These are passed to each
2544     * process when the bindApplication() IPC is sent to the process. They're
2545     * lazily setup to make sure the services are running when they're asked for.
2546     */
2547    private HashMap<String, IBinder> getCommonServicesLocked() {
2548        if (mAppBindArgs == null) {
2549            mAppBindArgs = new HashMap<String, IBinder>();
2550
2551            // Setup the application init args
2552            mAppBindArgs.put("package", ServiceManager.getService("package"));
2553            mAppBindArgs.put("window", ServiceManager.getService("window"));
2554            mAppBindArgs.put(Context.ALARM_SERVICE,
2555                    ServiceManager.getService(Context.ALARM_SERVICE));
2556        }
2557        return mAppBindArgs;
2558    }
2559
2560    final void setFocusedActivityLocked(ActivityRecord r) {
2561        if (mFocusedActivity != r) {
2562            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2563            mFocusedActivity = r;
2564            if (r.task != null && r.task.voiceInteractor != null) {
2565                startRunningVoiceLocked();
2566            } else {
2567                finishRunningVoiceLocked();
2568            }
2569            mStackSupervisor.setFocusedStack(r);
2570            if (r != null) {
2571                mWindowManager.setFocusedApp(r.appToken, true);
2572            }
2573            applyUpdateLockStateLocked(r);
2574        }
2575    }
2576
2577    final void clearFocusedActivity(ActivityRecord r) {
2578        if (mFocusedActivity == r) {
2579            mFocusedActivity = null;
2580        }
2581    }
2582
2583    @Override
2584    public void setFocusedStack(int stackId) {
2585        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2586        synchronized (ActivityManagerService.this) {
2587            ActivityStack stack = mStackSupervisor.getStack(stackId);
2588            if (stack != null) {
2589                ActivityRecord r = stack.topRunningActivityLocked(null);
2590                if (r != null) {
2591                    setFocusedActivityLocked(r);
2592                }
2593            }
2594        }
2595    }
2596
2597    @Override
2598    public void notifyActivityDrawn(IBinder token) {
2599        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2600        synchronized (this) {
2601            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2602            if (r != null) {
2603                r.task.stack.notifyActivityDrawnLocked(r);
2604            }
2605        }
2606    }
2607
2608    final void applyUpdateLockStateLocked(ActivityRecord r) {
2609        // Modifications to the UpdateLock state are done on our handler, outside
2610        // the activity manager's locks.  The new state is determined based on the
2611        // state *now* of the relevant activity record.  The object is passed to
2612        // the handler solely for logging detail, not to be consulted/modified.
2613        final boolean nextState = r != null && r.immersive;
2614        mHandler.sendMessage(
2615                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2616    }
2617
2618    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2619        Message msg = Message.obtain();
2620        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2621        msg.obj = r.task.askedCompatMode ? null : r;
2622        mHandler.sendMessage(msg);
2623    }
2624
2625    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2626            String what, Object obj, ProcessRecord srcApp) {
2627        app.lastActivityTime = now;
2628
2629        if (app.activities.size() > 0) {
2630            // Don't want to touch dependent processes that are hosting activities.
2631            return index;
2632        }
2633
2634        int lrui = mLruProcesses.lastIndexOf(app);
2635        if (lrui < 0) {
2636            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2637                    + what + " " + obj + " from " + srcApp);
2638            return index;
2639        }
2640
2641        if (lrui >= index) {
2642            // Don't want to cause this to move dependent processes *back* in the
2643            // list as if they were less frequently used.
2644            return index;
2645        }
2646
2647        if (lrui >= mLruProcessActivityStart) {
2648            // Don't want to touch dependent processes that are hosting activities.
2649            return index;
2650        }
2651
2652        mLruProcesses.remove(lrui);
2653        if (index > 0) {
2654            index--;
2655        }
2656        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2657                + " in LRU list: " + app);
2658        mLruProcesses.add(index, app);
2659        return index;
2660    }
2661
2662    final void removeLruProcessLocked(ProcessRecord app) {
2663        int lrui = mLruProcesses.lastIndexOf(app);
2664        if (lrui >= 0) {
2665            if (!app.killed) {
2666                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2667                Process.killProcessQuiet(app.pid);
2668                Process.killProcessGroup(app.info.uid, app.pid);
2669            }
2670            if (lrui <= mLruProcessActivityStart) {
2671                mLruProcessActivityStart--;
2672            }
2673            if (lrui <= mLruProcessServiceStart) {
2674                mLruProcessServiceStart--;
2675            }
2676            mLruProcesses.remove(lrui);
2677        }
2678    }
2679
2680    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2681            ProcessRecord client) {
2682        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2683                || app.treatLikeActivity;
2684        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2685        if (!activityChange && hasActivity) {
2686            // The process has activities, so we are only allowing activity-based adjustments
2687            // to move it.  It should be kept in the front of the list with other
2688            // processes that have activities, and we don't want those to change their
2689            // order except due to activity operations.
2690            return;
2691        }
2692
2693        mLruSeq++;
2694        final long now = SystemClock.uptimeMillis();
2695        app.lastActivityTime = now;
2696
2697        // First a quick reject: if the app is already at the position we will
2698        // put it, then there is nothing to do.
2699        if (hasActivity) {
2700            final int N = mLruProcesses.size();
2701            if (N > 0 && mLruProcesses.get(N-1) == app) {
2702                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2703                return;
2704            }
2705        } else {
2706            if (mLruProcessServiceStart > 0
2707                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2708                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2709                return;
2710            }
2711        }
2712
2713        int lrui = mLruProcesses.lastIndexOf(app);
2714
2715        if (app.persistent && lrui >= 0) {
2716            // We don't care about the position of persistent processes, as long as
2717            // they are in the list.
2718            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2719            return;
2720        }
2721
2722        /* In progress: compute new position first, so we can avoid doing work
2723           if the process is not actually going to move.  Not yet working.
2724        int addIndex;
2725        int nextIndex;
2726        boolean inActivity = false, inService = false;
2727        if (hasActivity) {
2728            // Process has activities, put it at the very tipsy-top.
2729            addIndex = mLruProcesses.size();
2730            nextIndex = mLruProcessServiceStart;
2731            inActivity = true;
2732        } else if (hasService) {
2733            // Process has services, put it at the top of the service list.
2734            addIndex = mLruProcessActivityStart;
2735            nextIndex = mLruProcessServiceStart;
2736            inActivity = true;
2737            inService = true;
2738        } else  {
2739            // Process not otherwise of interest, it goes to the top of the non-service area.
2740            addIndex = mLruProcessServiceStart;
2741            if (client != null) {
2742                int clientIndex = mLruProcesses.lastIndexOf(client);
2743                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2744                        + app);
2745                if (clientIndex >= 0 && addIndex > clientIndex) {
2746                    addIndex = clientIndex;
2747                }
2748            }
2749            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2750        }
2751
2752        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2753                + mLruProcessActivityStart + "): " + app);
2754        */
2755
2756        if (lrui >= 0) {
2757            if (lrui < mLruProcessActivityStart) {
2758                mLruProcessActivityStart--;
2759            }
2760            if (lrui < mLruProcessServiceStart) {
2761                mLruProcessServiceStart--;
2762            }
2763            /*
2764            if (addIndex > lrui) {
2765                addIndex--;
2766            }
2767            if (nextIndex > lrui) {
2768                nextIndex--;
2769            }
2770            */
2771            mLruProcesses.remove(lrui);
2772        }
2773
2774        /*
2775        mLruProcesses.add(addIndex, app);
2776        if (inActivity) {
2777            mLruProcessActivityStart++;
2778        }
2779        if (inService) {
2780            mLruProcessActivityStart++;
2781        }
2782        */
2783
2784        int nextIndex;
2785        if (hasActivity) {
2786            final int N = mLruProcesses.size();
2787            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2788                // Process doesn't have activities, but has clients with
2789                // activities...  move it up, but one below the top (the top
2790                // should always have a real activity).
2791                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2792                mLruProcesses.add(N-1, app);
2793                // To keep it from spamming the LRU list (by making a bunch of clients),
2794                // we will push down any other entries owned by the app.
2795                final int uid = app.info.uid;
2796                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2797                    ProcessRecord subProc = mLruProcesses.get(i);
2798                    if (subProc.info.uid == uid) {
2799                        // We want to push this one down the list.  If the process after
2800                        // it is for the same uid, however, don't do so, because we don't
2801                        // want them internally to be re-ordered.
2802                        if (mLruProcesses.get(i-1).info.uid != uid) {
2803                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2804                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2805                            ProcessRecord tmp = mLruProcesses.get(i);
2806                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2807                            mLruProcesses.set(i-1, tmp);
2808                            i--;
2809                        }
2810                    } else {
2811                        // A gap, we can stop here.
2812                        break;
2813                    }
2814                }
2815            } else {
2816                // Process has activities, put it at the very tipsy-top.
2817                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2818                mLruProcesses.add(app);
2819            }
2820            nextIndex = mLruProcessServiceStart;
2821        } else if (hasService) {
2822            // Process has services, put it at the top of the service list.
2823            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2824            mLruProcesses.add(mLruProcessActivityStart, app);
2825            nextIndex = mLruProcessServiceStart;
2826            mLruProcessActivityStart++;
2827        } else  {
2828            // Process not otherwise of interest, it goes to the top of the non-service area.
2829            int index = mLruProcessServiceStart;
2830            if (client != null) {
2831                // If there is a client, don't allow the process to be moved up higher
2832                // in the list than that client.
2833                int clientIndex = mLruProcesses.lastIndexOf(client);
2834                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2835                        + " when updating " + app);
2836                if (clientIndex <= lrui) {
2837                    // Don't allow the client index restriction to push it down farther in the
2838                    // list than it already is.
2839                    clientIndex = lrui;
2840                }
2841                if (clientIndex >= 0 && index > clientIndex) {
2842                    index = clientIndex;
2843                }
2844            }
2845            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2846            mLruProcesses.add(index, app);
2847            nextIndex = index-1;
2848            mLruProcessActivityStart++;
2849            mLruProcessServiceStart++;
2850        }
2851
2852        // If the app is currently using a content provider or service,
2853        // bump those processes as well.
2854        for (int j=app.connections.size()-1; j>=0; j--) {
2855            ConnectionRecord cr = app.connections.valueAt(j);
2856            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2857                    && cr.binding.service.app != null
2858                    && cr.binding.service.app.lruSeq != mLruSeq
2859                    && !cr.binding.service.app.persistent) {
2860                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2861                        "service connection", cr, app);
2862            }
2863        }
2864        for (int j=app.conProviders.size()-1; j>=0; j--) {
2865            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2866            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2867                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2868                        "provider reference", cpr, app);
2869            }
2870        }
2871    }
2872
2873    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2874        if (uid == Process.SYSTEM_UID) {
2875            // The system gets to run in any process.  If there are multiple
2876            // processes with the same uid, just pick the first (this
2877            // should never happen).
2878            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2879            if (procs == null) return null;
2880            final int N = procs.size();
2881            for (int i = 0; i < N; i++) {
2882                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2883            }
2884        }
2885        ProcessRecord proc = mProcessNames.get(processName, uid);
2886        if (false && proc != null && !keepIfLarge
2887                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2888                && proc.lastCachedPss >= 4000) {
2889            // Turn this condition on to cause killing to happen regularly, for testing.
2890            if (proc.baseProcessTracker != null) {
2891                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2892            }
2893            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2894        } else if (proc != null && !keepIfLarge
2895                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2896                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2897            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2898            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2899                if (proc.baseProcessTracker != null) {
2900                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2901                }
2902                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2903            }
2904        }
2905        return proc;
2906    }
2907
2908    void ensurePackageDexOpt(String packageName) {
2909        IPackageManager pm = AppGlobals.getPackageManager();
2910        try {
2911            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2912                mDidDexOpt = true;
2913            }
2914        } catch (RemoteException e) {
2915        }
2916    }
2917
2918    boolean isNextTransitionForward() {
2919        int transit = mWindowManager.getPendingAppTransition();
2920        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2921                || transit == AppTransition.TRANSIT_TASK_OPEN
2922                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2923    }
2924
2925    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2926            String processName, String abiOverride, int uid, Runnable crashHandler) {
2927        synchronized(this) {
2928            ApplicationInfo info = new ApplicationInfo();
2929            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2930            // For isolated processes, the former contains the parent's uid and the latter the
2931            // actual uid of the isolated process.
2932            // In the special case introduced by this method (which is, starting an isolated
2933            // process directly from the SystemServer without an actual parent app process) the
2934            // closest thing to a parent's uid is SYSTEM_UID.
2935            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2936            // the |isolated| logic in the ProcessRecord constructor.
2937            info.uid = Process.SYSTEM_UID;
2938            info.processName = processName;
2939            info.className = entryPoint;
2940            info.packageName = "android";
2941            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2942                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2943                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2944                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2945                    crashHandler);
2946            return proc != null ? proc.pid : 0;
2947        }
2948    }
2949
2950    final ProcessRecord startProcessLocked(String processName,
2951            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2952            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2953            boolean isolated, boolean keepIfLarge) {
2954        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2955                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2956                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2957                null /* crashHandler */);
2958    }
2959
2960    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2961            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2962            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2963            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2964        long startTime = SystemClock.elapsedRealtime();
2965        ProcessRecord app;
2966        if (!isolated) {
2967            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2968            checkTime(startTime, "startProcess: after getProcessRecord");
2969        } else {
2970            // If this is an isolated process, it can't re-use an existing process.
2971            app = null;
2972        }
2973        // We don't have to do anything more if:
2974        // (1) There is an existing application record; and
2975        // (2) The caller doesn't think it is dead, OR there is no thread
2976        //     object attached to it so we know it couldn't have crashed; and
2977        // (3) There is a pid assigned to it, so it is either starting or
2978        //     already running.
2979        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2980                + " app=" + app + " knownToBeDead=" + knownToBeDead
2981                + " thread=" + (app != null ? app.thread : null)
2982                + " pid=" + (app != null ? app.pid : -1));
2983        if (app != null && app.pid > 0) {
2984            if (!knownToBeDead || app.thread == null) {
2985                // We already have the app running, or are waiting for it to
2986                // come up (we have a pid but not yet its thread), so keep it.
2987                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2988                // If this is a new package in the process, add the package to the list
2989                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2990                checkTime(startTime, "startProcess: done, added package to proc");
2991                return app;
2992            }
2993
2994            // An application record is attached to a previous process,
2995            // clean it up now.
2996            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2997            checkTime(startTime, "startProcess: bad proc running, killing");
2998            Process.killProcessGroup(app.info.uid, app.pid);
2999            handleAppDiedLocked(app, true, true);
3000            checkTime(startTime, "startProcess: done killing old proc");
3001        }
3002
3003        String hostingNameStr = hostingName != null
3004                ? hostingName.flattenToShortString() : null;
3005
3006        if (!isolated) {
3007            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
3008                // If we are in the background, then check to see if this process
3009                // is bad.  If so, we will just silently fail.
3010                if (mBadProcesses.get(info.processName, info.uid) != null) {
3011                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3012                            + "/" + info.processName);
3013                    return null;
3014                }
3015            } else {
3016                // When the user is explicitly starting a process, then clear its
3017                // crash count so that we won't make it bad until they see at
3018                // least one crash dialog again, and make the process good again
3019                // if it had been bad.
3020                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3021                        + "/" + info.processName);
3022                mProcessCrashTimes.remove(info.processName, info.uid);
3023                if (mBadProcesses.get(info.processName, info.uid) != null) {
3024                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3025                            UserHandle.getUserId(info.uid), info.uid,
3026                            info.processName);
3027                    mBadProcesses.remove(info.processName, info.uid);
3028                    if (app != null) {
3029                        app.bad = false;
3030                    }
3031                }
3032            }
3033        }
3034
3035        if (app == null) {
3036            checkTime(startTime, "startProcess: creating new process record");
3037            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3038            app.crashHandler = crashHandler;
3039            if (app == null) {
3040                Slog.w(TAG, "Failed making new process record for "
3041                        + processName + "/" + info.uid + " isolated=" + isolated);
3042                return null;
3043            }
3044            mProcessNames.put(processName, app.uid, app);
3045            if (isolated) {
3046                mIsolatedProcesses.put(app.uid, app);
3047            }
3048            checkTime(startTime, "startProcess: done creating new process record");
3049        } else {
3050            // If this is a new package in the process, add the package to the list
3051            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3052            checkTime(startTime, "startProcess: added package to existing proc");
3053        }
3054
3055        // If the system is not ready yet, then hold off on starting this
3056        // process until it is.
3057        if (!mProcessesReady
3058                && !isAllowedWhileBooting(info)
3059                && !allowWhileBooting) {
3060            if (!mProcessesOnHold.contains(app)) {
3061                mProcessesOnHold.add(app);
3062            }
3063            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3064            checkTime(startTime, "startProcess: returning with proc on hold");
3065            return app;
3066        }
3067
3068        checkTime(startTime, "startProcess: stepping in to startProcess");
3069        startProcessLocked(
3070                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3071        checkTime(startTime, "startProcess: done starting proc!");
3072        return (app.pid != 0) ? app : null;
3073    }
3074
3075    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3076        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3077    }
3078
3079    private final void startProcessLocked(ProcessRecord app,
3080            String hostingType, String hostingNameStr) {
3081        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3082                null /* entryPoint */, null /* entryPointArgs */);
3083    }
3084
3085    private final void startProcessLocked(ProcessRecord app, String hostingType,
3086            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3087        long startTime = SystemClock.elapsedRealtime();
3088        if (app.pid > 0 && app.pid != MY_PID) {
3089            checkTime(startTime, "startProcess: removing from pids map");
3090            synchronized (mPidsSelfLocked) {
3091                mPidsSelfLocked.remove(app.pid);
3092                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3093            }
3094            checkTime(startTime, "startProcess: done removing from pids map");
3095            app.setPid(0);
3096        }
3097
3098        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3099                "startProcessLocked removing on hold: " + app);
3100        mProcessesOnHold.remove(app);
3101
3102        checkTime(startTime, "startProcess: starting to update cpu stats");
3103        updateCpuStats();
3104        checkTime(startTime, "startProcess: done updating cpu stats");
3105
3106        try {
3107            int uid = app.uid;
3108
3109            int[] gids = null;
3110            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3111            if (!app.isolated) {
3112                int[] permGids = null;
3113                try {
3114                    checkTime(startTime, "startProcess: getting gids from package manager");
3115                    final PackageManager pm = mContext.getPackageManager();
3116                    permGids = pm.getPackageGids(app.info.packageName);
3117
3118                    if (Environment.isExternalStorageEmulated()) {
3119                        checkTime(startTime, "startProcess: checking external storage perm");
3120                        if (pm.checkPermission(
3121                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3122                                app.info.packageName) == PERMISSION_GRANTED) {
3123                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3124                        } else {
3125                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3126                        }
3127                    }
3128                } catch (PackageManager.NameNotFoundException e) {
3129                    Slog.w(TAG, "Unable to retrieve gids", e);
3130                }
3131
3132                /*
3133                 * Add shared application and profile GIDs so applications can share some
3134                 * resources like shared libraries and access user-wide resources
3135                 */
3136                if (permGids == null) {
3137                    gids = new int[2];
3138                } else {
3139                    gids = new int[permGids.length + 2];
3140                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3141                }
3142                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3143                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3144            }
3145            checkTime(startTime, "startProcess: building args");
3146            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3147                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3148                        && mTopComponent != null
3149                        && app.processName.equals(mTopComponent.getPackageName())) {
3150                    uid = 0;
3151                }
3152                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3153                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3154                    uid = 0;
3155                }
3156            }
3157            int debugFlags = 0;
3158            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3159                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3160                // Also turn on CheckJNI for debuggable apps. It's quite
3161                // awkward to turn on otherwise.
3162                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3163            }
3164            // Run the app in safe mode if its manifest requests so or the
3165            // system is booted in safe mode.
3166            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3167                mSafeMode == true) {
3168                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3169            }
3170            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3171                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3172            }
3173            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3174                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3175            }
3176            if ("1".equals(SystemProperties.get("debug.assert"))) {
3177                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3178            }
3179
3180            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3181            if (requiredAbi == null) {
3182                requiredAbi = Build.SUPPORTED_ABIS[0];
3183            }
3184
3185            String instructionSet = null;
3186            if (app.info.primaryCpuAbi != null) {
3187                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3188            }
3189
3190            // Start the process.  It will either succeed and return a result containing
3191            // the PID of the new process, or else throw a RuntimeException.
3192            boolean isActivityProcess = (entryPoint == null);
3193            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3194            checkTime(startTime, "startProcess: asking zygote to start proc");
3195            Process.ProcessStartResult startResult = Process.start(entryPoint,
3196                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3197                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3198                    app.info.dataDir, entryPointArgs);
3199            checkTime(startTime, "startProcess: returned from zygote!");
3200
3201            if (app.isolated) {
3202                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3203            }
3204            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3205            checkTime(startTime, "startProcess: done updating battery stats");
3206
3207            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3208                    UserHandle.getUserId(uid), startResult.pid, uid,
3209                    app.processName, hostingType,
3210                    hostingNameStr != null ? hostingNameStr : "");
3211
3212            if (app.persistent) {
3213                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3214            }
3215
3216            checkTime(startTime, "startProcess: building log message");
3217            StringBuilder buf = mStringBuilder;
3218            buf.setLength(0);
3219            buf.append("Start proc ");
3220            buf.append(app.processName);
3221            if (!isActivityProcess) {
3222                buf.append(" [");
3223                buf.append(entryPoint);
3224                buf.append("]");
3225            }
3226            buf.append(" for ");
3227            buf.append(hostingType);
3228            if (hostingNameStr != null) {
3229                buf.append(" ");
3230                buf.append(hostingNameStr);
3231            }
3232            buf.append(": pid=");
3233            buf.append(startResult.pid);
3234            buf.append(" uid=");
3235            buf.append(uid);
3236            buf.append(" gids={");
3237            if (gids != null) {
3238                for (int gi=0; gi<gids.length; gi++) {
3239                    if (gi != 0) buf.append(", ");
3240                    buf.append(gids[gi]);
3241
3242                }
3243            }
3244            buf.append("}");
3245            if (requiredAbi != null) {
3246                buf.append(" abi=");
3247                buf.append(requiredAbi);
3248            }
3249            Slog.i(TAG, buf.toString());
3250            app.setPid(startResult.pid);
3251            app.usingWrapper = startResult.usingWrapper;
3252            app.removed = false;
3253            app.killed = false;
3254            app.killedByAm = false;
3255            checkTime(startTime, "startProcess: starting to update pids map");
3256            synchronized (mPidsSelfLocked) {
3257                this.mPidsSelfLocked.put(startResult.pid, app);
3258                if (isActivityProcess) {
3259                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3260                    msg.obj = app;
3261                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3262                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3263                }
3264            }
3265            checkTime(startTime, "startProcess: done updating pids map");
3266        } catch (RuntimeException e) {
3267            // XXX do better error recovery.
3268            app.setPid(0);
3269            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3270            if (app.isolated) {
3271                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3272            }
3273            Slog.e(TAG, "Failure starting process " + app.processName, e);
3274        }
3275    }
3276
3277    void updateUsageStats(ActivityRecord component, boolean resumed) {
3278        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3279        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3280        if (resumed) {
3281            if (mUsageStatsService != null) {
3282                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3283                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3284            }
3285            synchronized (stats) {
3286                stats.noteActivityResumedLocked(component.app.uid);
3287            }
3288        } else {
3289            if (mUsageStatsService != null) {
3290                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3291                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3292            }
3293            synchronized (stats) {
3294                stats.noteActivityPausedLocked(component.app.uid);
3295            }
3296        }
3297    }
3298
3299    Intent getHomeIntent() {
3300        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3301        intent.setComponent(mTopComponent);
3302        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3303            intent.addCategory(Intent.CATEGORY_HOME);
3304        }
3305        return intent;
3306    }
3307
3308    boolean startHomeActivityLocked(int userId) {
3309        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3310                && mTopAction == null) {
3311            // We are running in factory test mode, but unable to find
3312            // the factory test app, so just sit around displaying the
3313            // error message and don't try to start anything.
3314            return false;
3315        }
3316        Intent intent = getHomeIntent();
3317        ActivityInfo aInfo =
3318            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3319        if (aInfo != null) {
3320            intent.setComponent(new ComponentName(
3321                    aInfo.applicationInfo.packageName, aInfo.name));
3322            // Don't do this if the home app is currently being
3323            // instrumented.
3324            aInfo = new ActivityInfo(aInfo);
3325            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3326            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3327                    aInfo.applicationInfo.uid, true);
3328            if (app == null || app.instrumentationClass == null) {
3329                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3330                mStackSupervisor.startHomeActivity(intent, aInfo);
3331            }
3332        }
3333
3334        return true;
3335    }
3336
3337    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3338        ActivityInfo ai = null;
3339        ComponentName comp = intent.getComponent();
3340        try {
3341            if (comp != null) {
3342                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3343            } else {
3344                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3345                        intent,
3346                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3347                            flags, userId);
3348
3349                if (info != null) {
3350                    ai = info.activityInfo;
3351                }
3352            }
3353        } catch (RemoteException e) {
3354            // ignore
3355        }
3356
3357        return ai;
3358    }
3359
3360    /**
3361     * Starts the "new version setup screen" if appropriate.
3362     */
3363    void startSetupActivityLocked() {
3364        // Only do this once per boot.
3365        if (mCheckedForSetup) {
3366            return;
3367        }
3368
3369        // We will show this screen if the current one is a different
3370        // version than the last one shown, and we are not running in
3371        // low-level factory test mode.
3372        final ContentResolver resolver = mContext.getContentResolver();
3373        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3374                Settings.Global.getInt(resolver,
3375                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3376            mCheckedForSetup = true;
3377
3378            // See if we should be showing the platform update setup UI.
3379            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3380            List<ResolveInfo> ris = mContext.getPackageManager()
3381                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3382
3383            // We don't allow third party apps to replace this.
3384            ResolveInfo ri = null;
3385            for (int i=0; ris != null && i<ris.size(); i++) {
3386                if ((ris.get(i).activityInfo.applicationInfo.flags
3387                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3388                    ri = ris.get(i);
3389                    break;
3390                }
3391            }
3392
3393            if (ri != null) {
3394                String vers = ri.activityInfo.metaData != null
3395                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3396                        : null;
3397                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3398                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3399                            Intent.METADATA_SETUP_VERSION);
3400                }
3401                String lastVers = Settings.Secure.getString(
3402                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3403                if (vers != null && !vers.equals(lastVers)) {
3404                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3405                    intent.setComponent(new ComponentName(
3406                            ri.activityInfo.packageName, ri.activityInfo.name));
3407                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3408                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3409                            null);
3410                }
3411            }
3412        }
3413    }
3414
3415    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3416        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3417    }
3418
3419    void enforceNotIsolatedCaller(String caller) {
3420        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3421            throw new SecurityException("Isolated process not allowed to call " + caller);
3422        }
3423    }
3424
3425    void enforceShellRestriction(String restriction, int userHandle) {
3426        if (Binder.getCallingUid() == Process.SHELL_UID) {
3427            if (userHandle < 0
3428                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3429                throw new SecurityException("Shell does not have permission to access user "
3430                        + userHandle);
3431            }
3432        }
3433    }
3434
3435    @Override
3436    public int getFrontActivityScreenCompatMode() {
3437        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3438        synchronized (this) {
3439            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3440        }
3441    }
3442
3443    @Override
3444    public void setFrontActivityScreenCompatMode(int mode) {
3445        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3446                "setFrontActivityScreenCompatMode");
3447        synchronized (this) {
3448            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3449        }
3450    }
3451
3452    @Override
3453    public int getPackageScreenCompatMode(String packageName) {
3454        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3455        synchronized (this) {
3456            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3457        }
3458    }
3459
3460    @Override
3461    public void setPackageScreenCompatMode(String packageName, int mode) {
3462        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3463                "setPackageScreenCompatMode");
3464        synchronized (this) {
3465            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3466        }
3467    }
3468
3469    @Override
3470    public boolean getPackageAskScreenCompat(String packageName) {
3471        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3472        synchronized (this) {
3473            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3474        }
3475    }
3476
3477    @Override
3478    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3479        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3480                "setPackageAskScreenCompat");
3481        synchronized (this) {
3482            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3483        }
3484    }
3485
3486    private void dispatchProcessesChanged() {
3487        int N;
3488        synchronized (this) {
3489            N = mPendingProcessChanges.size();
3490            if (mActiveProcessChanges.length < N) {
3491                mActiveProcessChanges = new ProcessChangeItem[N];
3492            }
3493            mPendingProcessChanges.toArray(mActiveProcessChanges);
3494            mAvailProcessChanges.addAll(mPendingProcessChanges);
3495            mPendingProcessChanges.clear();
3496            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3497        }
3498
3499        int i = mProcessObservers.beginBroadcast();
3500        while (i > 0) {
3501            i--;
3502            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3503            if (observer != null) {
3504                try {
3505                    for (int j=0; j<N; j++) {
3506                        ProcessChangeItem item = mActiveProcessChanges[j];
3507                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3508                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3509                                    + item.pid + " uid=" + item.uid + ": "
3510                                    + item.foregroundActivities);
3511                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3512                                    item.foregroundActivities);
3513                        }
3514                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3515                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3516                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3517                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3518                        }
3519                    }
3520                } catch (RemoteException e) {
3521                }
3522            }
3523        }
3524        mProcessObservers.finishBroadcast();
3525    }
3526
3527    private void dispatchProcessDied(int pid, int uid) {
3528        int i = mProcessObservers.beginBroadcast();
3529        while (i > 0) {
3530            i--;
3531            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3532            if (observer != null) {
3533                try {
3534                    observer.onProcessDied(pid, uid);
3535                } catch (RemoteException e) {
3536                }
3537            }
3538        }
3539        mProcessObservers.finishBroadcast();
3540    }
3541
3542    @Override
3543    public final int startActivity(IApplicationThread caller, String callingPackage,
3544            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3545            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3546        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3547            resultWho, requestCode, startFlags, profilerInfo, options,
3548            UserHandle.getCallingUserId());
3549    }
3550
3551    @Override
3552    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3553            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3554            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3555        enforceNotIsolatedCaller("startActivity");
3556        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3557                false, ALLOW_FULL_ONLY, "startActivity", null);
3558        // TODO: Switch to user app stacks here.
3559        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3560                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3561                profilerInfo, null, null, options, userId, null, null);
3562    }
3563
3564    @Override
3565    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3566            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3567            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3568
3569        // This is very dangerous -- it allows you to perform a start activity (including
3570        // permission grants) as any app that may launch one of your own activities.  So
3571        // we will only allow this to be done from activities that are part of the core framework,
3572        // and then only when they are running as the system.
3573        final ActivityRecord sourceRecord;
3574        final int targetUid;
3575        final String targetPackage;
3576        synchronized (this) {
3577            if (resultTo == null) {
3578                throw new SecurityException("Must be called from an activity");
3579            }
3580            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3581            if (sourceRecord == null) {
3582                throw new SecurityException("Called with bad activity token: " + resultTo);
3583            }
3584            if (!sourceRecord.info.packageName.equals("android")) {
3585                throw new SecurityException(
3586                        "Must be called from an activity that is declared in the android package");
3587            }
3588            if (sourceRecord.app == null) {
3589                throw new SecurityException("Called without a process attached to activity");
3590            }
3591            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3592                // This is still okay, as long as this activity is running under the
3593                // uid of the original calling activity.
3594                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3595                    throw new SecurityException(
3596                            "Calling activity in uid " + sourceRecord.app.uid
3597                                    + " must be system uid or original calling uid "
3598                                    + sourceRecord.launchedFromUid);
3599                }
3600            }
3601            targetUid = sourceRecord.launchedFromUid;
3602            targetPackage = sourceRecord.launchedFromPackage;
3603        }
3604
3605        if (userId == UserHandle.USER_NULL) {
3606            userId = UserHandle.getUserId(sourceRecord.app.uid);
3607        }
3608
3609        // TODO: Switch to user app stacks here.
3610        try {
3611            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3612                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3613                    null, null, options, userId, null, null);
3614            return ret;
3615        } catch (SecurityException e) {
3616            // XXX need to figure out how to propagate to original app.
3617            // A SecurityException here is generally actually a fault of the original
3618            // calling activity (such as a fairly granting permissions), so propagate it
3619            // back to them.
3620            /*
3621            StringBuilder msg = new StringBuilder();
3622            msg.append("While launching");
3623            msg.append(intent.toString());
3624            msg.append(": ");
3625            msg.append(e.getMessage());
3626            */
3627            throw e;
3628        }
3629    }
3630
3631    @Override
3632    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3633            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3634            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3635        enforceNotIsolatedCaller("startActivityAndWait");
3636        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3637                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3638        WaitResult res = new WaitResult();
3639        // TODO: Switch to user app stacks here.
3640        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3641                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3642                options, userId, null, null);
3643        return res;
3644    }
3645
3646    @Override
3647    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3648            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3649            int startFlags, Configuration config, Bundle options, int userId) {
3650        enforceNotIsolatedCaller("startActivityWithConfig");
3651        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3652                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3653        // TODO: Switch to user app stacks here.
3654        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3655                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3656                null, null, config, options, userId, null, null);
3657        return ret;
3658    }
3659
3660    @Override
3661    public int startActivityIntentSender(IApplicationThread caller,
3662            IntentSender intent, Intent fillInIntent, String resolvedType,
3663            IBinder resultTo, String resultWho, int requestCode,
3664            int flagsMask, int flagsValues, Bundle options) {
3665        enforceNotIsolatedCaller("startActivityIntentSender");
3666        // Refuse possible leaked file descriptors
3667        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3668            throw new IllegalArgumentException("File descriptors passed in Intent");
3669        }
3670
3671        IIntentSender sender = intent.getTarget();
3672        if (!(sender instanceof PendingIntentRecord)) {
3673            throw new IllegalArgumentException("Bad PendingIntent object");
3674        }
3675
3676        PendingIntentRecord pir = (PendingIntentRecord)sender;
3677
3678        synchronized (this) {
3679            // If this is coming from the currently resumed activity, it is
3680            // effectively saying that app switches are allowed at this point.
3681            final ActivityStack stack = getFocusedStack();
3682            if (stack.mResumedActivity != null &&
3683                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3684                mAppSwitchesAllowedTime = 0;
3685            }
3686        }
3687        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3688                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3689        return ret;
3690    }
3691
3692    @Override
3693    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3694            Intent intent, String resolvedType, IVoiceInteractionSession session,
3695            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3696            Bundle options, int userId) {
3697        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3698                != PackageManager.PERMISSION_GRANTED) {
3699            String msg = "Permission Denial: startVoiceActivity() from pid="
3700                    + Binder.getCallingPid()
3701                    + ", uid=" + Binder.getCallingUid()
3702                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3703            Slog.w(TAG, msg);
3704            throw new SecurityException(msg);
3705        }
3706        if (session == null || interactor == null) {
3707            throw new NullPointerException("null session or interactor");
3708        }
3709        userId = handleIncomingUser(callingPid, callingUid, userId,
3710                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3711        // TODO: Switch to user app stacks here.
3712        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3713                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3714                null, options, userId, null, null);
3715    }
3716
3717    @Override
3718    public boolean startNextMatchingActivity(IBinder callingActivity,
3719            Intent intent, Bundle options) {
3720        // Refuse possible leaked file descriptors
3721        if (intent != null && intent.hasFileDescriptors() == true) {
3722            throw new IllegalArgumentException("File descriptors passed in Intent");
3723        }
3724
3725        synchronized (this) {
3726            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3727            if (r == null) {
3728                ActivityOptions.abort(options);
3729                return false;
3730            }
3731            if (r.app == null || r.app.thread == null) {
3732                // The caller is not running...  d'oh!
3733                ActivityOptions.abort(options);
3734                return false;
3735            }
3736            intent = new Intent(intent);
3737            // The caller is not allowed to change the data.
3738            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3739            // And we are resetting to find the next component...
3740            intent.setComponent(null);
3741
3742            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3743
3744            ActivityInfo aInfo = null;
3745            try {
3746                List<ResolveInfo> resolves =
3747                    AppGlobals.getPackageManager().queryIntentActivities(
3748                            intent, r.resolvedType,
3749                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3750                            UserHandle.getCallingUserId());
3751
3752                // Look for the original activity in the list...
3753                final int N = resolves != null ? resolves.size() : 0;
3754                for (int i=0; i<N; i++) {
3755                    ResolveInfo rInfo = resolves.get(i);
3756                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3757                            && rInfo.activityInfo.name.equals(r.info.name)) {
3758                        // We found the current one...  the next matching is
3759                        // after it.
3760                        i++;
3761                        if (i<N) {
3762                            aInfo = resolves.get(i).activityInfo;
3763                        }
3764                        if (debug) {
3765                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3766                                    + "/" + r.info.name);
3767                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3768                                    + "/" + aInfo.name);
3769                        }
3770                        break;
3771                    }
3772                }
3773            } catch (RemoteException e) {
3774            }
3775
3776            if (aInfo == null) {
3777                // Nobody who is next!
3778                ActivityOptions.abort(options);
3779                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3780                return false;
3781            }
3782
3783            intent.setComponent(new ComponentName(
3784                    aInfo.applicationInfo.packageName, aInfo.name));
3785            intent.setFlags(intent.getFlags()&~(
3786                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3787                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3788                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3789                    Intent.FLAG_ACTIVITY_NEW_TASK));
3790
3791            // Okay now we need to start the new activity, replacing the
3792            // currently running activity.  This is a little tricky because
3793            // we want to start the new one as if the current one is finished,
3794            // but not finish the current one first so that there is no flicker.
3795            // And thus...
3796            final boolean wasFinishing = r.finishing;
3797            r.finishing = true;
3798
3799            // Propagate reply information over to the new activity.
3800            final ActivityRecord resultTo = r.resultTo;
3801            final String resultWho = r.resultWho;
3802            final int requestCode = r.requestCode;
3803            r.resultTo = null;
3804            if (resultTo != null) {
3805                resultTo.removeResultsLocked(r, resultWho, requestCode);
3806            }
3807
3808            final long origId = Binder.clearCallingIdentity();
3809            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3810                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3811                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3812                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3813            Binder.restoreCallingIdentity(origId);
3814
3815            r.finishing = wasFinishing;
3816            if (res != ActivityManager.START_SUCCESS) {
3817                return false;
3818            }
3819            return true;
3820        }
3821    }
3822
3823    @Override
3824    public final int startActivityFromRecents(int taskId, Bundle options) {
3825        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3826            String msg = "Permission Denial: startActivityFromRecents called without " +
3827                    START_TASKS_FROM_RECENTS;
3828            Slog.w(TAG, msg);
3829            throw new SecurityException(msg);
3830        }
3831        return startActivityFromRecentsInner(taskId, options);
3832    }
3833
3834    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3835        final TaskRecord task;
3836        final int callingUid;
3837        final String callingPackage;
3838        final Intent intent;
3839        final int userId;
3840        synchronized (this) {
3841            task = recentTaskForIdLocked(taskId);
3842            if (task == null) {
3843                throw new IllegalArgumentException("Task " + taskId + " not found.");
3844            }
3845            callingUid = task.mCallingUid;
3846            callingPackage = task.mCallingPackage;
3847            intent = task.intent;
3848            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3849            userId = task.userId;
3850        }
3851        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3852                options, userId, null, task);
3853    }
3854
3855    final int startActivityInPackage(int uid, String callingPackage,
3856            Intent intent, String resolvedType, IBinder resultTo,
3857            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3858            IActivityContainer container, TaskRecord inTask) {
3859
3860        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3861                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3862
3863        // TODO: Switch to user app stacks here.
3864        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3865                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3866                null, null, null, options, userId, container, inTask);
3867        return ret;
3868    }
3869
3870    @Override
3871    public final int startActivities(IApplicationThread caller, String callingPackage,
3872            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3873            int userId) {
3874        enforceNotIsolatedCaller("startActivities");
3875        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3876                false, ALLOW_FULL_ONLY, "startActivity", null);
3877        // TODO: Switch to user app stacks here.
3878        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3879                resolvedTypes, resultTo, options, userId);
3880        return ret;
3881    }
3882
3883    final int startActivitiesInPackage(int uid, String callingPackage,
3884            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3885            Bundle options, int userId) {
3886
3887        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3888                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3889        // TODO: Switch to user app stacks here.
3890        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3891                resultTo, options, userId);
3892        return ret;
3893    }
3894
3895    //explicitly remove thd old information in mRecentTasks when removing existing user.
3896    private void removeRecentTasksForUserLocked(int userId) {
3897        if(userId <= 0) {
3898            Slog.i(TAG, "Can't remove recent task on user " + userId);
3899            return;
3900        }
3901
3902        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3903            TaskRecord tr = mRecentTasks.get(i);
3904            if (tr.userId == userId) {
3905                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3906                        + " when finishing user" + userId);
3907                mRecentTasks.remove(i);
3908                tr.removedFromRecents(mTaskPersister);
3909            }
3910        }
3911
3912        // Remove tasks from persistent storage.
3913        mTaskPersister.wakeup(null, true);
3914    }
3915
3916    // Sort by taskId
3917    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3918        @Override
3919        public int compare(TaskRecord lhs, TaskRecord rhs) {
3920            return rhs.taskId - lhs.taskId;
3921        }
3922    };
3923
3924    // Extract the affiliates of the chain containing mRecentTasks[start].
3925    private int processNextAffiliateChain(int start) {
3926        final TaskRecord startTask = mRecentTasks.get(start);
3927        final int affiliateId = startTask.mAffiliatedTaskId;
3928
3929        // Quick identification of isolated tasks. I.e. those not launched behind.
3930        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3931                startTask.mNextAffiliate == null) {
3932            // There is still a slim chance that there are other tasks that point to this task
3933            // and that the chain is so messed up that this task no longer points to them but
3934            // the gain of this optimization outweighs the risk.
3935            startTask.inRecents = true;
3936            return start + 1;
3937        }
3938
3939        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3940        mTmpRecents.clear();
3941        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3942            final TaskRecord task = mRecentTasks.get(i);
3943            if (task.mAffiliatedTaskId == affiliateId) {
3944                mRecentTasks.remove(i);
3945                mTmpRecents.add(task);
3946            }
3947        }
3948
3949        // Sort them all by taskId. That is the order they were create in and that order will
3950        // always be correct.
3951        Collections.sort(mTmpRecents, mTaskRecordComparator);
3952
3953        // Go through and fix up the linked list.
3954        // The first one is the end of the chain and has no next.
3955        final TaskRecord first = mTmpRecents.get(0);
3956        first.inRecents = true;
3957        if (first.mNextAffiliate != null) {
3958            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3959            first.setNextAffiliate(null);
3960            mTaskPersister.wakeup(first, false);
3961        }
3962        // Everything in the middle is doubly linked from next to prev.
3963        final int tmpSize = mTmpRecents.size();
3964        for (int i = 0; i < tmpSize - 1; ++i) {
3965            final TaskRecord next = mTmpRecents.get(i);
3966            final TaskRecord prev = mTmpRecents.get(i + 1);
3967            if (next.mPrevAffiliate != prev) {
3968                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3969                        " setting prev=" + prev);
3970                next.setPrevAffiliate(prev);
3971                mTaskPersister.wakeup(next, false);
3972            }
3973            if (prev.mNextAffiliate != next) {
3974                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3975                        " setting next=" + next);
3976                prev.setNextAffiliate(next);
3977                mTaskPersister.wakeup(prev, false);
3978            }
3979            prev.inRecents = true;
3980        }
3981        // The last one is the beginning of the list and has no prev.
3982        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3983        if (last.mPrevAffiliate != null) {
3984            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3985            last.setPrevAffiliate(null);
3986            mTaskPersister.wakeup(last, false);
3987        }
3988
3989        // Insert the group back into mRecentTasks at start.
3990        mRecentTasks.addAll(start, mTmpRecents);
3991
3992        // Let the caller know where we left off.
3993        return start + tmpSize;
3994    }
3995
3996    /**
3997     * Update the recent tasks lists: make sure tasks should still be here (their
3998     * applications / activities still exist), update their availability, fixup ordering
3999     * of affiliations.
4000     */
4001    void cleanupRecentTasksLocked(int userId) {
4002        if (mRecentTasks == null) {
4003            // Happens when called from the packagemanager broadcast before boot.
4004            return;
4005        }
4006
4007        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
4008        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
4009        final IPackageManager pm = AppGlobals.getPackageManager();
4010        final ActivityInfo dummyAct = new ActivityInfo();
4011        final ApplicationInfo dummyApp = new ApplicationInfo();
4012
4013        int N = mRecentTasks.size();
4014
4015        int[] users = userId == UserHandle.USER_ALL
4016                ? getUsersLocked() : new int[] { userId };
4017        for (int user : users) {
4018            for (int i = 0; i < N; i++) {
4019                TaskRecord task = mRecentTasks.get(i);
4020                if (task.userId != user) {
4021                    // Only look at tasks for the user ID of interest.
4022                    continue;
4023                }
4024                if (task.autoRemoveRecents && task.getTopActivity() == null) {
4025                    // This situation is broken, and we should just get rid of it now.
4026                    mRecentTasks.remove(i);
4027                    task.removedFromRecents(mTaskPersister);
4028                    i--;
4029                    N--;
4030                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
4031                    continue;
4032                }
4033                // Check whether this activity is currently available.
4034                if (task.realActivity != null) {
4035                    ActivityInfo ai = availActCache.get(task.realActivity);
4036                    if (ai == null) {
4037                        try {
4038                            ai = pm.getActivityInfo(task.realActivity,
4039                                    PackageManager.GET_UNINSTALLED_PACKAGES
4040                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
4041                        } catch (RemoteException e) {
4042                            // Will never happen.
4043                            continue;
4044                        }
4045                        if (ai == null) {
4046                            ai = dummyAct;
4047                        }
4048                        availActCache.put(task.realActivity, ai);
4049                    }
4050                    if (ai == dummyAct) {
4051                        // This could be either because the activity no longer exists, or the
4052                        // app is temporarily gone.  For the former we want to remove the recents
4053                        // entry; for the latter we want to mark it as unavailable.
4054                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4055                        if (app == null) {
4056                            try {
4057                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4058                                        PackageManager.GET_UNINSTALLED_PACKAGES
4059                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4060                            } catch (RemoteException e) {
4061                                // Will never happen.
4062                                continue;
4063                            }
4064                            if (app == null) {
4065                                app = dummyApp;
4066                            }
4067                            availAppCache.put(task.realActivity.getPackageName(), app);
4068                        }
4069                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4070                            // Doesn't exist any more!  Good-bye.
4071                            mRecentTasks.remove(i);
4072                            task.removedFromRecents(mTaskPersister);
4073                            i--;
4074                            N--;
4075                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4076                            continue;
4077                        } else {
4078                            // Otherwise just not available for now.
4079                            if (task.isAvailable) {
4080                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4081                                        + task);
4082                            }
4083                            task.isAvailable = false;
4084                        }
4085                    } else {
4086                        if (!ai.enabled || !ai.applicationInfo.enabled
4087                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4088                            if (task.isAvailable) {
4089                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4090                                        + task + " (enabled=" + ai.enabled + "/"
4091                                        + ai.applicationInfo.enabled +  " flags="
4092                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4093                            }
4094                            task.isAvailable = false;
4095                        } else {
4096                            if (!task.isAvailable) {
4097                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4098                                        + task);
4099                            }
4100                            task.isAvailable = true;
4101                        }
4102                    }
4103                }
4104            }
4105        }
4106
4107        // Verify the affiliate chain for each task.
4108        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4109        }
4110
4111        mTmpRecents.clear();
4112        // mRecentTasks is now in sorted, affiliated order.
4113    }
4114
4115    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4116        int N = mRecentTasks.size();
4117        TaskRecord top = task;
4118        int topIndex = taskIndex;
4119        while (top.mNextAffiliate != null && topIndex > 0) {
4120            top = top.mNextAffiliate;
4121            topIndex--;
4122        }
4123        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4124                + topIndex + " from intial " + taskIndex);
4125        // Find the end of the chain, doing a sanity check along the way.
4126        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4127        int endIndex = topIndex;
4128        TaskRecord prev = top;
4129        while (endIndex < N) {
4130            TaskRecord cur = mRecentTasks.get(endIndex);
4131            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4132                    + endIndex + " " + cur);
4133            if (cur == top) {
4134                // Verify start of the chain.
4135                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4136                    Slog.wtf(TAG, "Bad chain @" + endIndex
4137                            + ": first task has next affiliate: " + prev);
4138                    sane = false;
4139                    break;
4140                }
4141            } else {
4142                // Verify middle of the chain's next points back to the one before.
4143                if (cur.mNextAffiliate != prev
4144                        || cur.mNextAffiliateTaskId != prev.taskId) {
4145                    Slog.wtf(TAG, "Bad chain @" + endIndex
4146                            + ": middle task " + cur + " @" + endIndex
4147                            + " has bad next affiliate "
4148                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4149                            + ", expected " + prev);
4150                    sane = false;
4151                    break;
4152                }
4153            }
4154            if (cur.mPrevAffiliateTaskId == -1) {
4155                // Chain ends here.
4156                if (cur.mPrevAffiliate != null) {
4157                    Slog.wtf(TAG, "Bad chain @" + endIndex
4158                            + ": last task " + cur + " has previous affiliate "
4159                            + cur.mPrevAffiliate);
4160                    sane = false;
4161                }
4162                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4163                break;
4164            } else {
4165                // Verify middle of the chain's prev points to a valid item.
4166                if (cur.mPrevAffiliate == null) {
4167                    Slog.wtf(TAG, "Bad chain @" + endIndex
4168                            + ": task " + cur + " has previous affiliate "
4169                            + cur.mPrevAffiliate + " but should be id "
4170                            + cur.mPrevAffiliate);
4171                    sane = false;
4172                    break;
4173                }
4174            }
4175            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4176                Slog.wtf(TAG, "Bad chain @" + endIndex
4177                        + ": task " + cur + " has affiliated id "
4178                        + cur.mAffiliatedTaskId + " but should be "
4179                        + task.mAffiliatedTaskId);
4180                sane = false;
4181                break;
4182            }
4183            prev = cur;
4184            endIndex++;
4185            if (endIndex >= N) {
4186                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4187                        + ": last task " + prev);
4188                sane = false;
4189                break;
4190            }
4191        }
4192        if (sane) {
4193            if (endIndex < taskIndex) {
4194                Slog.wtf(TAG, "Bad chain @" + endIndex
4195                        + ": did not extend to task " + task + " @" + taskIndex);
4196                sane = false;
4197            }
4198        }
4199        if (sane) {
4200            // All looks good, we can just move all of the affiliated tasks
4201            // to the top.
4202            for (int i=topIndex; i<=endIndex; i++) {
4203                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4204                        + " from " + i + " to " + (i-topIndex));
4205                TaskRecord cur = mRecentTasks.remove(i);
4206                mRecentTasks.add(i-topIndex, cur);
4207            }
4208            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4209                    + " to " + endIndex);
4210            return true;
4211        }
4212
4213        // Whoops, couldn't do it.
4214        return false;
4215    }
4216
4217    final void addRecentTaskLocked(TaskRecord task) {
4218        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4219                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4220
4221        int N = mRecentTasks.size();
4222        // Quick case: check if the top-most recent task is the same.
4223        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4224            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4225            return;
4226        }
4227        // Another quick case: check if this is part of a set of affiliated
4228        // tasks that are at the top.
4229        if (isAffiliated && N > 0 && task.inRecents
4230                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4231            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4232                    + " at top when adding " + task);
4233            return;
4234        }
4235        // Another quick case: never add voice sessions.
4236        if (task.voiceSession != null) {
4237            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4238            return;
4239        }
4240
4241        boolean needAffiliationFix = false;
4242
4243        // Slightly less quick case: the task is already in recents, so all we need
4244        // to do is move it.
4245        if (task.inRecents) {
4246            int taskIndex = mRecentTasks.indexOf(task);
4247            if (taskIndex >= 0) {
4248                if (!isAffiliated) {
4249                    // Simple case: this is not an affiliated task, so we just move it to the front.
4250                    mRecentTasks.remove(taskIndex);
4251                    mRecentTasks.add(0, task);
4252                    notifyTaskPersisterLocked(task, false);
4253                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4254                            + " from " + taskIndex);
4255                    return;
4256                } else {
4257                    // More complicated: need to keep all affiliated tasks together.
4258                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4259                        // All went well.
4260                        return;
4261                    }
4262
4263                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4264                    // everything and then go through our general path of adding a new task.
4265                    needAffiliationFix = true;
4266                }
4267            } else {
4268                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4269                needAffiliationFix = true;
4270            }
4271        }
4272
4273        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4274        trimRecentsForTask(task, true);
4275
4276        N = mRecentTasks.size();
4277        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4278            final TaskRecord tr = mRecentTasks.remove(N - 1);
4279            tr.removedFromRecents(mTaskPersister);
4280            N--;
4281        }
4282        task.inRecents = true;
4283        if (!isAffiliated || needAffiliationFix) {
4284            // If this is a simple non-affiliated task, or we had some failure trying to
4285            // handle it as part of an affilated task, then just place it at the top.
4286            mRecentTasks.add(0, task);
4287        } else if (isAffiliated) {
4288            // If this is a new affiliated task, then move all of the affiliated tasks
4289            // to the front and insert this new one.
4290            TaskRecord other = task.mNextAffiliate;
4291            if (other == null) {
4292                other = task.mPrevAffiliate;
4293            }
4294            if (other != null) {
4295                int otherIndex = mRecentTasks.indexOf(other);
4296                if (otherIndex >= 0) {
4297                    // Insert new task at appropriate location.
4298                    int taskIndex;
4299                    if (other == task.mNextAffiliate) {
4300                        // We found the index of our next affiliation, which is who is
4301                        // before us in the list, so add after that point.
4302                        taskIndex = otherIndex+1;
4303                    } else {
4304                        // We found the index of our previous affiliation, which is who is
4305                        // after us in the list, so add at their position.
4306                        taskIndex = otherIndex;
4307                    }
4308                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4309                            + taskIndex + ": " + task);
4310                    mRecentTasks.add(taskIndex, task);
4311
4312                    // Now move everything to the front.
4313                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4314                        // All went well.
4315                        return;
4316                    }
4317
4318                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4319                    // everything and then go through our general path of adding a new task.
4320                    needAffiliationFix = true;
4321                } else {
4322                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4323                            + other);
4324                    needAffiliationFix = true;
4325                }
4326            } else {
4327                if (DEBUG_RECENTS) Slog.d(TAG,
4328                        "addRecent: adding affiliated task without next/prev:" + task);
4329                needAffiliationFix = true;
4330            }
4331        }
4332        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4333
4334        if (needAffiliationFix) {
4335            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4336            cleanupRecentTasksLocked(task.userId);
4337        }
4338    }
4339
4340    /**
4341     * If needed, remove oldest existing entries in recents that are for the same kind
4342     * of task as the given one.
4343     */
4344    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4345        int N = mRecentTasks.size();
4346        final Intent intent = task.intent;
4347        final boolean document = intent != null && intent.isDocument();
4348
4349        int maxRecents = task.maxRecents - 1;
4350        for (int i=0; i<N; i++) {
4351            final TaskRecord tr = mRecentTasks.get(i);
4352            if (task != tr) {
4353                if (task.userId != tr.userId) {
4354                    continue;
4355                }
4356                if (i > MAX_RECENT_BITMAPS) {
4357                    tr.freeLastThumbnail();
4358                }
4359                final Intent trIntent = tr.intent;
4360                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4361                    (intent == null || !intent.filterEquals(trIntent))) {
4362                    continue;
4363                }
4364                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4365                if (document && trIsDocument) {
4366                    // These are the same document activity (not necessarily the same doc).
4367                    if (maxRecents > 0) {
4368                        --maxRecents;
4369                        continue;
4370                    }
4371                    // Hit the maximum number of documents for this task. Fall through
4372                    // and remove this document from recents.
4373                } else if (document || trIsDocument) {
4374                    // Only one of these is a document. Not the droid we're looking for.
4375                    continue;
4376                }
4377            }
4378
4379            if (!doTrim) {
4380                // If the caller is not actually asking for a trim, just tell them we reached
4381                // a point where the trim would happen.
4382                return i;
4383            }
4384
4385            // Either task and tr are the same or, their affinities match or their intents match
4386            // and neither of them is a document, or they are documents using the same activity
4387            // and their maxRecents has been reached.
4388            tr.disposeThumbnail();
4389            mRecentTasks.remove(i);
4390            if (task != tr) {
4391                tr.removedFromRecents(mTaskPersister);
4392            }
4393            i--;
4394            N--;
4395            if (task.intent == null) {
4396                // If the new recent task we are adding is not fully
4397                // specified, then replace it with the existing recent task.
4398                task = tr;
4399            }
4400            notifyTaskPersisterLocked(tr, false);
4401        }
4402
4403        return -1;
4404    }
4405
4406    @Override
4407    public void reportActivityFullyDrawn(IBinder token) {
4408        synchronized (this) {
4409            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4410            if (r == null) {
4411                return;
4412            }
4413            r.reportFullyDrawnLocked();
4414        }
4415    }
4416
4417    @Override
4418    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4419        synchronized (this) {
4420            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4421            if (r == null) {
4422                return;
4423            }
4424            final long origId = Binder.clearCallingIdentity();
4425            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4426            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4427                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4428            if (config != null) {
4429                r.frozenBeforeDestroy = true;
4430                if (!updateConfigurationLocked(config, r, false, false)) {
4431                    mStackSupervisor.resumeTopActivitiesLocked();
4432                }
4433            }
4434            Binder.restoreCallingIdentity(origId);
4435        }
4436    }
4437
4438    @Override
4439    public int getRequestedOrientation(IBinder token) {
4440        synchronized (this) {
4441            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4442            if (r == null) {
4443                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4444            }
4445            return mWindowManager.getAppOrientation(r.appToken);
4446        }
4447    }
4448
4449    /**
4450     * This is the internal entry point for handling Activity.finish().
4451     *
4452     * @param token The Binder token referencing the Activity we want to finish.
4453     * @param resultCode Result code, if any, from this Activity.
4454     * @param resultData Result data (Intent), if any, from this Activity.
4455     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4456     *            the root Activity in the task.
4457     *
4458     * @return Returns true if the activity successfully finished, or false if it is still running.
4459     */
4460    @Override
4461    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4462            boolean finishTask) {
4463        // Refuse possible leaked file descriptors
4464        if (resultData != null && resultData.hasFileDescriptors() == true) {
4465            throw new IllegalArgumentException("File descriptors passed in Intent");
4466        }
4467
4468        synchronized(this) {
4469            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4470            if (r == null) {
4471                return true;
4472            }
4473            // Keep track of the root activity of the task before we finish it
4474            TaskRecord tr = r.task;
4475            ActivityRecord rootR = tr.getRootActivity();
4476            // Do not allow task to finish in Lock Task mode.
4477            if (tr == mStackSupervisor.mLockTaskModeTask) {
4478                if (rootR == r) {
4479                    mStackSupervisor.showLockTaskToast();
4480                    return false;
4481                }
4482            }
4483            if (mController != null) {
4484                // Find the first activity that is not finishing.
4485                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4486                if (next != null) {
4487                    // ask watcher if this is allowed
4488                    boolean resumeOK = true;
4489                    try {
4490                        resumeOK = mController.activityResuming(next.packageName);
4491                    } catch (RemoteException e) {
4492                        mController = null;
4493                        Watchdog.getInstance().setActivityController(null);
4494                    }
4495
4496                    if (!resumeOK) {
4497                        return false;
4498                    }
4499                }
4500            }
4501            final long origId = Binder.clearCallingIdentity();
4502            try {
4503                boolean res;
4504                if (finishTask && r == rootR) {
4505                    // If requested, remove the task that is associated to this activity only if it
4506                    // was the root activity in the task.  The result code and data is ignored because
4507                    // we don't support returning them across task boundaries.
4508                    res = removeTaskByIdLocked(tr.taskId, 0);
4509                } else {
4510                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4511                            resultData, "app-request", true);
4512                }
4513                return res;
4514            } finally {
4515                Binder.restoreCallingIdentity(origId);
4516            }
4517        }
4518    }
4519
4520    @Override
4521    public final void finishHeavyWeightApp() {
4522        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4523                != PackageManager.PERMISSION_GRANTED) {
4524            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4525                    + Binder.getCallingPid()
4526                    + ", uid=" + Binder.getCallingUid()
4527                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4528            Slog.w(TAG, msg);
4529            throw new SecurityException(msg);
4530        }
4531
4532        synchronized(this) {
4533            if (mHeavyWeightProcess == null) {
4534                return;
4535            }
4536
4537            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4538                    mHeavyWeightProcess.activities);
4539            for (int i=0; i<activities.size(); i++) {
4540                ActivityRecord r = activities.get(i);
4541                if (!r.finishing) {
4542                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4543                            null, "finish-heavy", true);
4544                }
4545            }
4546
4547            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4548                    mHeavyWeightProcess.userId, 0));
4549            mHeavyWeightProcess = null;
4550        }
4551    }
4552
4553    @Override
4554    public void crashApplication(int uid, int initialPid, String packageName,
4555            String message) {
4556        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4557                != PackageManager.PERMISSION_GRANTED) {
4558            String msg = "Permission Denial: crashApplication() from pid="
4559                    + Binder.getCallingPid()
4560                    + ", uid=" + Binder.getCallingUid()
4561                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4562            Slog.w(TAG, msg);
4563            throw new SecurityException(msg);
4564        }
4565
4566        synchronized(this) {
4567            ProcessRecord proc = null;
4568
4569            // Figure out which process to kill.  We don't trust that initialPid
4570            // still has any relation to current pids, so must scan through the
4571            // list.
4572            synchronized (mPidsSelfLocked) {
4573                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4574                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4575                    if (p.uid != uid) {
4576                        continue;
4577                    }
4578                    if (p.pid == initialPid) {
4579                        proc = p;
4580                        break;
4581                    }
4582                    if (p.pkgList.containsKey(packageName)) {
4583                        proc = p;
4584                    }
4585                }
4586            }
4587
4588            if (proc == null) {
4589                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4590                        + " initialPid=" + initialPid
4591                        + " packageName=" + packageName);
4592                return;
4593            }
4594
4595            if (proc.thread != null) {
4596                if (proc.pid == Process.myPid()) {
4597                    Log.w(TAG, "crashApplication: trying to crash self!");
4598                    return;
4599                }
4600                long ident = Binder.clearCallingIdentity();
4601                try {
4602                    proc.thread.scheduleCrash(message);
4603                } catch (RemoteException e) {
4604                }
4605                Binder.restoreCallingIdentity(ident);
4606            }
4607        }
4608    }
4609
4610    @Override
4611    public final void finishSubActivity(IBinder token, String resultWho,
4612            int requestCode) {
4613        synchronized(this) {
4614            final long origId = Binder.clearCallingIdentity();
4615            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4616            if (r != null) {
4617                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4618            }
4619            Binder.restoreCallingIdentity(origId);
4620        }
4621    }
4622
4623    @Override
4624    public boolean finishActivityAffinity(IBinder token) {
4625        synchronized(this) {
4626            final long origId = Binder.clearCallingIdentity();
4627            try {
4628                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4629
4630                ActivityRecord rootR = r.task.getRootActivity();
4631                // Do not allow task to finish in Lock Task mode.
4632                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4633                    if (rootR == r) {
4634                        mStackSupervisor.showLockTaskToast();
4635                        return false;
4636                    }
4637                }
4638                boolean res = false;
4639                if (r != null) {
4640                    res = r.task.stack.finishActivityAffinityLocked(r);
4641                }
4642                return res;
4643            } finally {
4644                Binder.restoreCallingIdentity(origId);
4645            }
4646        }
4647    }
4648
4649    @Override
4650    public void finishVoiceTask(IVoiceInteractionSession session) {
4651        synchronized(this) {
4652            final long origId = Binder.clearCallingIdentity();
4653            try {
4654                mStackSupervisor.finishVoiceTask(session);
4655            } finally {
4656                Binder.restoreCallingIdentity(origId);
4657            }
4658        }
4659
4660    }
4661
4662    @Override
4663    public boolean releaseActivityInstance(IBinder token) {
4664        synchronized(this) {
4665            final long origId = Binder.clearCallingIdentity();
4666            try {
4667                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4668                if (r.task == null || r.task.stack == null) {
4669                    return false;
4670                }
4671                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4672            } finally {
4673                Binder.restoreCallingIdentity(origId);
4674            }
4675        }
4676    }
4677
4678    @Override
4679    public void releaseSomeActivities(IApplicationThread appInt) {
4680        synchronized(this) {
4681            final long origId = Binder.clearCallingIdentity();
4682            try {
4683                ProcessRecord app = getRecordForAppLocked(appInt);
4684                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4685            } finally {
4686                Binder.restoreCallingIdentity(origId);
4687            }
4688        }
4689    }
4690
4691    @Override
4692    public boolean willActivityBeVisible(IBinder token) {
4693        synchronized(this) {
4694            ActivityStack stack = ActivityRecord.getStackLocked(token);
4695            if (stack != null) {
4696                return stack.willActivityBeVisibleLocked(token);
4697            }
4698            return false;
4699        }
4700    }
4701
4702    @Override
4703    public void overridePendingTransition(IBinder token, String packageName,
4704            int enterAnim, int exitAnim) {
4705        synchronized(this) {
4706            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4707            if (self == null) {
4708                return;
4709            }
4710
4711            final long origId = Binder.clearCallingIdentity();
4712
4713            if (self.state == ActivityState.RESUMED
4714                    || self.state == ActivityState.PAUSING) {
4715                mWindowManager.overridePendingAppTransition(packageName,
4716                        enterAnim, exitAnim, null);
4717            }
4718
4719            Binder.restoreCallingIdentity(origId);
4720        }
4721    }
4722
4723    /**
4724     * Main function for removing an existing process from the activity manager
4725     * as a result of that process going away.  Clears out all connections
4726     * to the process.
4727     */
4728    private final void handleAppDiedLocked(ProcessRecord app,
4729            boolean restarting, boolean allowRestart) {
4730        int pid = app.pid;
4731        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4732        if (!kept && !restarting) {
4733            removeLruProcessLocked(app);
4734            if (pid > 0) {
4735                ProcessList.remove(pid);
4736            }
4737        }
4738
4739        if (mProfileProc == app) {
4740            clearProfilerLocked();
4741        }
4742
4743        // Remove this application's activities from active lists.
4744        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4745
4746        app.activities.clear();
4747
4748        if (app.instrumentationClass != null) {
4749            Slog.w(TAG, "Crash of app " + app.processName
4750                  + " running instrumentation " + app.instrumentationClass);
4751            Bundle info = new Bundle();
4752            info.putString("shortMsg", "Process crashed.");
4753            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4754        }
4755
4756        if (!restarting) {
4757            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4758                // If there was nothing to resume, and we are not already
4759                // restarting this process, but there is a visible activity that
4760                // is hosted by the process...  then make sure all visible
4761                // activities are running, taking care of restarting this
4762                // process.
4763                if (hasVisibleActivities) {
4764                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4765                }
4766            }
4767        }
4768    }
4769
4770    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4771        IBinder threadBinder = thread.asBinder();
4772        // Find the application record.
4773        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4774            ProcessRecord rec = mLruProcesses.get(i);
4775            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4776                return i;
4777            }
4778        }
4779        return -1;
4780    }
4781
4782    final ProcessRecord getRecordForAppLocked(
4783            IApplicationThread thread) {
4784        if (thread == null) {
4785            return null;
4786        }
4787
4788        int appIndex = getLRURecordIndexForAppLocked(thread);
4789        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4790    }
4791
4792    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4793        // If there are no longer any background processes running,
4794        // and the app that died was not running instrumentation,
4795        // then tell everyone we are now low on memory.
4796        boolean haveBg = false;
4797        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4798            ProcessRecord rec = mLruProcesses.get(i);
4799            if (rec.thread != null
4800                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4801                haveBg = true;
4802                break;
4803            }
4804        }
4805
4806        if (!haveBg) {
4807            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4808            if (doReport) {
4809                long now = SystemClock.uptimeMillis();
4810                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4811                    doReport = false;
4812                } else {
4813                    mLastMemUsageReportTime = now;
4814                }
4815            }
4816            final ArrayList<ProcessMemInfo> memInfos
4817                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4818            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4819            long now = SystemClock.uptimeMillis();
4820            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4821                ProcessRecord rec = mLruProcesses.get(i);
4822                if (rec == dyingProc || rec.thread == null) {
4823                    continue;
4824                }
4825                if (doReport) {
4826                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4827                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4828                }
4829                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4830                    // The low memory report is overriding any current
4831                    // state for a GC request.  Make sure to do
4832                    // heavy/important/visible/foreground processes first.
4833                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4834                        rec.lastRequestedGc = 0;
4835                    } else {
4836                        rec.lastRequestedGc = rec.lastLowMemory;
4837                    }
4838                    rec.reportLowMemory = true;
4839                    rec.lastLowMemory = now;
4840                    mProcessesToGc.remove(rec);
4841                    addProcessToGcListLocked(rec);
4842                }
4843            }
4844            if (doReport) {
4845                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4846                mHandler.sendMessage(msg);
4847            }
4848            scheduleAppGcsLocked();
4849        }
4850    }
4851
4852    final void appDiedLocked(ProcessRecord app) {
4853       appDiedLocked(app, app.pid, app.thread);
4854    }
4855
4856    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4857        // First check if this ProcessRecord is actually active for the pid.
4858        synchronized (mPidsSelfLocked) {
4859            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4860            if (curProc != app) {
4861                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4862                return;
4863            }
4864        }
4865
4866        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4867        synchronized (stats) {
4868            stats.noteProcessDiedLocked(app.info.uid, pid);
4869        }
4870
4871        Process.killProcessQuiet(pid);
4872        Process.killProcessGroup(app.info.uid, pid);
4873        app.killed = true;
4874
4875        // Clean up already done if the process has been re-started.
4876        if (app.pid == pid && app.thread != null &&
4877                app.thread.asBinder() == thread.asBinder()) {
4878            boolean doLowMem = app.instrumentationClass == null;
4879            boolean doOomAdj = doLowMem;
4880            if (!app.killedByAm) {
4881                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4882                        + ") has died");
4883                mAllowLowerMemLevel = true;
4884            } else {
4885                // Note that we always want to do oom adj to update our state with the
4886                // new number of procs.
4887                mAllowLowerMemLevel = false;
4888                doLowMem = false;
4889            }
4890            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4891            if (DEBUG_CLEANUP) Slog.v(
4892                TAG, "Dying app: " + app + ", pid: " + pid
4893                + ", thread: " + thread.asBinder());
4894            handleAppDiedLocked(app, false, true);
4895
4896            if (doOomAdj) {
4897                updateOomAdjLocked();
4898            }
4899            if (doLowMem) {
4900                doLowMemReportIfNeededLocked(app);
4901            }
4902        } else if (app.pid != pid) {
4903            // A new process has already been started.
4904            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4905                    + ") has died and restarted (pid " + app.pid + ").");
4906            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4907        } else if (DEBUG_PROCESSES) {
4908            Slog.d(TAG, "Received spurious death notification for thread "
4909                    + thread.asBinder());
4910        }
4911    }
4912
4913    /**
4914     * If a stack trace dump file is configured, dump process stack traces.
4915     * @param clearTraces causes the dump file to be erased prior to the new
4916     *    traces being written, if true; when false, the new traces will be
4917     *    appended to any existing file content.
4918     * @param firstPids of dalvik VM processes to dump stack traces for first
4919     * @param lastPids of dalvik VM processes to dump stack traces for last
4920     * @param nativeProcs optional list of native process names to dump stack crawls
4921     * @return file containing stack traces, or null if no dump file is configured
4922     */
4923    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4924            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4925        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4926        if (tracesPath == null || tracesPath.length() == 0) {
4927            return null;
4928        }
4929
4930        File tracesFile = new File(tracesPath);
4931        try {
4932            File tracesDir = tracesFile.getParentFile();
4933            if (!tracesDir.exists()) {
4934                tracesDir.mkdirs();
4935                if (!SELinux.restorecon(tracesDir)) {
4936                    return null;
4937                }
4938            }
4939            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4940
4941            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4942            tracesFile.createNewFile();
4943            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4944        } catch (IOException e) {
4945            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4946            return null;
4947        }
4948
4949        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4950        return tracesFile;
4951    }
4952
4953    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4954            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4955        // Use a FileObserver to detect when traces finish writing.
4956        // The order of traces is considered important to maintain for legibility.
4957        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4958            @Override
4959            public synchronized void onEvent(int event, String path) { notify(); }
4960        };
4961
4962        try {
4963            observer.startWatching();
4964
4965            // First collect all of the stacks of the most important pids.
4966            if (firstPids != null) {
4967                try {
4968                    int num = firstPids.size();
4969                    for (int i = 0; i < num; i++) {
4970                        synchronized (observer) {
4971                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4972                            observer.wait(200);  // Wait for write-close, give up after 200msec
4973                        }
4974                    }
4975                } catch (InterruptedException e) {
4976                    Slog.wtf(TAG, e);
4977                }
4978            }
4979
4980            // Next collect the stacks of the native pids
4981            if (nativeProcs != null) {
4982                int[] pids = Process.getPidsForCommands(nativeProcs);
4983                if (pids != null) {
4984                    for (int pid : pids) {
4985                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4986                    }
4987                }
4988            }
4989
4990            // Lastly, measure CPU usage.
4991            if (processCpuTracker != null) {
4992                processCpuTracker.init();
4993                System.gc();
4994                processCpuTracker.update();
4995                try {
4996                    synchronized (processCpuTracker) {
4997                        processCpuTracker.wait(500); // measure over 1/2 second.
4998                    }
4999                } catch (InterruptedException e) {
5000                }
5001                processCpuTracker.update();
5002
5003                // We'll take the stack crawls of just the top apps using CPU.
5004                final int N = processCpuTracker.countWorkingStats();
5005                int numProcs = 0;
5006                for (int i=0; i<N && numProcs<5; i++) {
5007                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5008                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5009                        numProcs++;
5010                        try {
5011                            synchronized (observer) {
5012                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5013                                observer.wait(200);  // Wait for write-close, give up after 200msec
5014                            }
5015                        } catch (InterruptedException e) {
5016                            Slog.wtf(TAG, e);
5017                        }
5018
5019                    }
5020                }
5021            }
5022        } finally {
5023            observer.stopWatching();
5024        }
5025    }
5026
5027    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5028        if (true || IS_USER_BUILD) {
5029            return;
5030        }
5031        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5032        if (tracesPath == null || tracesPath.length() == 0) {
5033            return;
5034        }
5035
5036        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5037        StrictMode.allowThreadDiskWrites();
5038        try {
5039            final File tracesFile = new File(tracesPath);
5040            final File tracesDir = tracesFile.getParentFile();
5041            final File tracesTmp = new File(tracesDir, "__tmp__");
5042            try {
5043                if (!tracesDir.exists()) {
5044                    tracesDir.mkdirs();
5045                    if (!SELinux.restorecon(tracesDir.getPath())) {
5046                        return;
5047                    }
5048                }
5049                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
5050
5051                if (tracesFile.exists()) {
5052                    tracesTmp.delete();
5053                    tracesFile.renameTo(tracesTmp);
5054                }
5055                StringBuilder sb = new StringBuilder();
5056                Time tobj = new Time();
5057                tobj.set(System.currentTimeMillis());
5058                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5059                sb.append(": ");
5060                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5061                sb.append(" since ");
5062                sb.append(msg);
5063                FileOutputStream fos = new FileOutputStream(tracesFile);
5064                fos.write(sb.toString().getBytes());
5065                if (app == null) {
5066                    fos.write("\n*** No application process!".getBytes());
5067                }
5068                fos.close();
5069                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5070            } catch (IOException e) {
5071                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5072                return;
5073            }
5074
5075            if (app != null) {
5076                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5077                firstPids.add(app.pid);
5078                dumpStackTraces(tracesPath, firstPids, null, null, null);
5079            }
5080
5081            File lastTracesFile = null;
5082            File curTracesFile = null;
5083            for (int i=9; i>=0; i--) {
5084                String name = String.format(Locale.US, "slow%02d.txt", i);
5085                curTracesFile = new File(tracesDir, name);
5086                if (curTracesFile.exists()) {
5087                    if (lastTracesFile != null) {
5088                        curTracesFile.renameTo(lastTracesFile);
5089                    } else {
5090                        curTracesFile.delete();
5091                    }
5092                }
5093                lastTracesFile = curTracesFile;
5094            }
5095            tracesFile.renameTo(curTracesFile);
5096            if (tracesTmp.exists()) {
5097                tracesTmp.renameTo(tracesFile);
5098            }
5099        } finally {
5100            StrictMode.setThreadPolicy(oldPolicy);
5101        }
5102    }
5103
5104    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5105            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5106        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5107        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5108
5109        if (mController != null) {
5110            try {
5111                // 0 == continue, -1 = kill process immediately
5112                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5113                if (res < 0 && app.pid != MY_PID) {
5114                    app.kill("anr", true);
5115                }
5116            } catch (RemoteException e) {
5117                mController = null;
5118                Watchdog.getInstance().setActivityController(null);
5119            }
5120        }
5121
5122        long anrTime = SystemClock.uptimeMillis();
5123        if (MONITOR_CPU_USAGE) {
5124            updateCpuStatsNow();
5125        }
5126
5127        synchronized (this) {
5128            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5129            if (mShuttingDown) {
5130                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5131                return;
5132            } else if (app.notResponding) {
5133                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5134                return;
5135            } else if (app.crashing) {
5136                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5137                return;
5138            }
5139
5140            // In case we come through here for the same app before completing
5141            // this one, mark as anring now so we will bail out.
5142            app.notResponding = true;
5143
5144            // Log the ANR to the event log.
5145            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5146                    app.processName, app.info.flags, annotation);
5147
5148            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5149            firstPids.add(app.pid);
5150
5151            int parentPid = app.pid;
5152            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5153            if (parentPid != app.pid) firstPids.add(parentPid);
5154
5155            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5156
5157            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5158                ProcessRecord r = mLruProcesses.get(i);
5159                if (r != null && r.thread != null) {
5160                    int pid = r.pid;
5161                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5162                        if (r.persistent) {
5163                            firstPids.add(pid);
5164                        } else {
5165                            lastPids.put(pid, Boolean.TRUE);
5166                        }
5167                    }
5168                }
5169            }
5170        }
5171
5172        // Log the ANR to the main log.
5173        StringBuilder info = new StringBuilder();
5174        info.setLength(0);
5175        info.append("ANR in ").append(app.processName);
5176        if (activity != null && activity.shortComponentName != null) {
5177            info.append(" (").append(activity.shortComponentName).append(")");
5178        }
5179        info.append("\n");
5180        info.append("PID: ").append(app.pid).append("\n");
5181        if (annotation != null) {
5182            info.append("Reason: ").append(annotation).append("\n");
5183        }
5184        if (parent != null && parent != activity) {
5185            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5186        }
5187
5188        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5189
5190        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5191                NATIVE_STACKS_OF_INTEREST);
5192
5193        String cpuInfo = null;
5194        if (MONITOR_CPU_USAGE) {
5195            updateCpuStatsNow();
5196            synchronized (mProcessCpuTracker) {
5197                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5198            }
5199            info.append(processCpuTracker.printCurrentLoad());
5200            info.append(cpuInfo);
5201        }
5202
5203        info.append(processCpuTracker.printCurrentState(anrTime));
5204
5205        Slog.e(TAG, info.toString());
5206        if (tracesFile == null) {
5207            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5208            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5209        }
5210
5211        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5212                cpuInfo, tracesFile, null);
5213
5214        if (mController != null) {
5215            try {
5216                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5217                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5218                if (res != 0) {
5219                    if (res < 0 && app.pid != MY_PID) {
5220                        app.kill("anr", true);
5221                    } else {
5222                        synchronized (this) {
5223                            mServices.scheduleServiceTimeoutLocked(app);
5224                        }
5225                    }
5226                    return;
5227                }
5228            } catch (RemoteException e) {
5229                mController = null;
5230                Watchdog.getInstance().setActivityController(null);
5231            }
5232        }
5233
5234        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5235        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5236                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5237
5238        synchronized (this) {
5239            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5240                app.kill("bg anr", true);
5241                return;
5242            }
5243
5244            // Set the app's notResponding state, and look up the errorReportReceiver
5245            makeAppNotRespondingLocked(app,
5246                    activity != null ? activity.shortComponentName : null,
5247                    annotation != null ? "ANR " + annotation : "ANR",
5248                    info.toString());
5249
5250            // Bring up the infamous App Not Responding dialog
5251            Message msg = Message.obtain();
5252            HashMap<String, Object> map = new HashMap<String, Object>();
5253            msg.what = SHOW_NOT_RESPONDING_MSG;
5254            msg.obj = map;
5255            msg.arg1 = aboveSystem ? 1 : 0;
5256            map.put("app", app);
5257            if (activity != null) {
5258                map.put("activity", activity);
5259            }
5260
5261            mHandler.sendMessage(msg);
5262        }
5263    }
5264
5265    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5266        if (!mLaunchWarningShown) {
5267            mLaunchWarningShown = true;
5268            mHandler.post(new Runnable() {
5269                @Override
5270                public void run() {
5271                    synchronized (ActivityManagerService.this) {
5272                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5273                        d.show();
5274                        mHandler.postDelayed(new Runnable() {
5275                            @Override
5276                            public void run() {
5277                                synchronized (ActivityManagerService.this) {
5278                                    d.dismiss();
5279                                    mLaunchWarningShown = false;
5280                                }
5281                            }
5282                        }, 4000);
5283                    }
5284                }
5285            });
5286        }
5287    }
5288
5289    @Override
5290    public boolean clearApplicationUserData(final String packageName,
5291            final IPackageDataObserver observer, int userId) {
5292        enforceNotIsolatedCaller("clearApplicationUserData");
5293        int uid = Binder.getCallingUid();
5294        int pid = Binder.getCallingPid();
5295        userId = handleIncomingUser(pid, uid,
5296                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5297        long callingId = Binder.clearCallingIdentity();
5298        try {
5299            IPackageManager pm = AppGlobals.getPackageManager();
5300            int pkgUid = -1;
5301            synchronized(this) {
5302                try {
5303                    pkgUid = pm.getPackageUid(packageName, userId);
5304                } catch (RemoteException e) {
5305                }
5306                if (pkgUid == -1) {
5307                    Slog.w(TAG, "Invalid packageName: " + packageName);
5308                    if (observer != null) {
5309                        try {
5310                            observer.onRemoveCompleted(packageName, false);
5311                        } catch (RemoteException e) {
5312                            Slog.i(TAG, "Observer no longer exists.");
5313                        }
5314                    }
5315                    return false;
5316                }
5317                if (uid == pkgUid || checkComponentPermission(
5318                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5319                        pid, uid, -1, true)
5320                        == PackageManager.PERMISSION_GRANTED) {
5321                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5322                } else {
5323                    throw new SecurityException("PID " + pid + " does not have permission "
5324                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5325                                    + " of package " + packageName);
5326                }
5327
5328                // Remove all tasks match the cleared application package and user
5329                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5330                    final TaskRecord tr = mRecentTasks.get(i);
5331                    final String taskPackageName =
5332                            tr.getBaseIntent().getComponent().getPackageName();
5333                    if (tr.userId != userId) continue;
5334                    if (!taskPackageName.equals(packageName)) continue;
5335                    removeTaskByIdLocked(tr.taskId, 0);
5336                }
5337            }
5338
5339            try {
5340                // Clear application user data
5341                pm.clearApplicationUserData(packageName, observer, userId);
5342
5343                synchronized(this) {
5344                    // Remove all permissions granted from/to this package
5345                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5346                }
5347
5348                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5349                        Uri.fromParts("package", packageName, null));
5350                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5351                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5352                        null, null, 0, null, null, null, false, false, userId);
5353            } catch (RemoteException e) {
5354            }
5355        } finally {
5356            Binder.restoreCallingIdentity(callingId);
5357        }
5358        return true;
5359    }
5360
5361    @Override
5362    public void killBackgroundProcesses(final String packageName, int userId) {
5363        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5364                != PackageManager.PERMISSION_GRANTED &&
5365                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5366                        != PackageManager.PERMISSION_GRANTED) {
5367            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5368                    + Binder.getCallingPid()
5369                    + ", uid=" + Binder.getCallingUid()
5370                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5371            Slog.w(TAG, msg);
5372            throw new SecurityException(msg);
5373        }
5374
5375        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5376                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5377        long callingId = Binder.clearCallingIdentity();
5378        try {
5379            IPackageManager pm = AppGlobals.getPackageManager();
5380            synchronized(this) {
5381                int appId = -1;
5382                try {
5383                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5384                } catch (RemoteException e) {
5385                }
5386                if (appId == -1) {
5387                    Slog.w(TAG, "Invalid packageName: " + packageName);
5388                    return;
5389                }
5390                killPackageProcessesLocked(packageName, appId, userId,
5391                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5392            }
5393        } finally {
5394            Binder.restoreCallingIdentity(callingId);
5395        }
5396    }
5397
5398    @Override
5399    public void killAllBackgroundProcesses() {
5400        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5401                != PackageManager.PERMISSION_GRANTED) {
5402            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5403                    + Binder.getCallingPid()
5404                    + ", uid=" + Binder.getCallingUid()
5405                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5406            Slog.w(TAG, msg);
5407            throw new SecurityException(msg);
5408        }
5409
5410        long callingId = Binder.clearCallingIdentity();
5411        try {
5412            synchronized(this) {
5413                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5414                final int NP = mProcessNames.getMap().size();
5415                for (int ip=0; ip<NP; ip++) {
5416                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5417                    final int NA = apps.size();
5418                    for (int ia=0; ia<NA; ia++) {
5419                        ProcessRecord app = apps.valueAt(ia);
5420                        if (app.persistent) {
5421                            // we don't kill persistent processes
5422                            continue;
5423                        }
5424                        if (app.removed) {
5425                            procs.add(app);
5426                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5427                            app.removed = true;
5428                            procs.add(app);
5429                        }
5430                    }
5431                }
5432
5433                int N = procs.size();
5434                for (int i=0; i<N; i++) {
5435                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5436                }
5437                mAllowLowerMemLevel = true;
5438                updateOomAdjLocked();
5439                doLowMemReportIfNeededLocked(null);
5440            }
5441        } finally {
5442            Binder.restoreCallingIdentity(callingId);
5443        }
5444    }
5445
5446    @Override
5447    public void forceStopPackage(final String packageName, int userId) {
5448        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5449                != PackageManager.PERMISSION_GRANTED) {
5450            String msg = "Permission Denial: forceStopPackage() from pid="
5451                    + Binder.getCallingPid()
5452                    + ", uid=" + Binder.getCallingUid()
5453                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5454            Slog.w(TAG, msg);
5455            throw new SecurityException(msg);
5456        }
5457        final int callingPid = Binder.getCallingPid();
5458        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5459                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5460        long callingId = Binder.clearCallingIdentity();
5461        try {
5462            IPackageManager pm = AppGlobals.getPackageManager();
5463            synchronized(this) {
5464                int[] users = userId == UserHandle.USER_ALL
5465                        ? getUsersLocked() : new int[] { userId };
5466                for (int user : users) {
5467                    int pkgUid = -1;
5468                    try {
5469                        pkgUid = pm.getPackageUid(packageName, user);
5470                    } catch (RemoteException e) {
5471                    }
5472                    if (pkgUid == -1) {
5473                        Slog.w(TAG, "Invalid packageName: " + packageName);
5474                        continue;
5475                    }
5476                    try {
5477                        pm.setPackageStoppedState(packageName, true, user);
5478                    } catch (RemoteException e) {
5479                    } catch (IllegalArgumentException e) {
5480                        Slog.w(TAG, "Failed trying to unstop package "
5481                                + packageName + ": " + e);
5482                    }
5483                    if (isUserRunningLocked(user, false)) {
5484                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5485                    }
5486                }
5487            }
5488        } finally {
5489            Binder.restoreCallingIdentity(callingId);
5490        }
5491    }
5492
5493    @Override
5494    public void addPackageDependency(String packageName) {
5495        synchronized (this) {
5496            int callingPid = Binder.getCallingPid();
5497            if (callingPid == Process.myPid()) {
5498                //  Yeah, um, no.
5499                Slog.w(TAG, "Can't addPackageDependency on system process");
5500                return;
5501            }
5502            ProcessRecord proc;
5503            synchronized (mPidsSelfLocked) {
5504                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5505            }
5506            if (proc != null) {
5507                if (proc.pkgDeps == null) {
5508                    proc.pkgDeps = new ArraySet<String>(1);
5509                }
5510                proc.pkgDeps.add(packageName);
5511            }
5512        }
5513    }
5514
5515    /*
5516     * The pkg name and app id have to be specified.
5517     */
5518    @Override
5519    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5520        if (pkg == null) {
5521            return;
5522        }
5523        // Make sure the uid is valid.
5524        if (appid < 0) {
5525            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5526            return;
5527        }
5528        int callerUid = Binder.getCallingUid();
5529        // Only the system server can kill an application
5530        if (callerUid == Process.SYSTEM_UID) {
5531            // Post an aysnc message to kill the application
5532            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5533            msg.arg1 = appid;
5534            msg.arg2 = 0;
5535            Bundle bundle = new Bundle();
5536            bundle.putString("pkg", pkg);
5537            bundle.putString("reason", reason);
5538            msg.obj = bundle;
5539            mHandler.sendMessage(msg);
5540        } else {
5541            throw new SecurityException(callerUid + " cannot kill pkg: " +
5542                    pkg);
5543        }
5544    }
5545
5546    @Override
5547    public void closeSystemDialogs(String reason) {
5548        enforceNotIsolatedCaller("closeSystemDialogs");
5549
5550        final int pid = Binder.getCallingPid();
5551        final int uid = Binder.getCallingUid();
5552        final long origId = Binder.clearCallingIdentity();
5553        try {
5554            synchronized (this) {
5555                // Only allow this from foreground processes, so that background
5556                // applications can't abuse it to prevent system UI from being shown.
5557                if (uid >= Process.FIRST_APPLICATION_UID) {
5558                    ProcessRecord proc;
5559                    synchronized (mPidsSelfLocked) {
5560                        proc = mPidsSelfLocked.get(pid);
5561                    }
5562                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5563                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5564                                + " from background process " + proc);
5565                        return;
5566                    }
5567                }
5568                closeSystemDialogsLocked(reason);
5569            }
5570        } finally {
5571            Binder.restoreCallingIdentity(origId);
5572        }
5573    }
5574
5575    void closeSystemDialogsLocked(String reason) {
5576        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5577        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5578                | Intent.FLAG_RECEIVER_FOREGROUND);
5579        if (reason != null) {
5580            intent.putExtra("reason", reason);
5581        }
5582        mWindowManager.closeSystemDialogs(reason);
5583
5584        mStackSupervisor.closeSystemDialogsLocked();
5585
5586        broadcastIntentLocked(null, null, intent, null,
5587                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5588                Process.SYSTEM_UID, UserHandle.USER_ALL);
5589    }
5590
5591    @Override
5592    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5593        enforceNotIsolatedCaller("getProcessMemoryInfo");
5594        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5595        for (int i=pids.length-1; i>=0; i--) {
5596            ProcessRecord proc;
5597            int oomAdj;
5598            synchronized (this) {
5599                synchronized (mPidsSelfLocked) {
5600                    proc = mPidsSelfLocked.get(pids[i]);
5601                    oomAdj = proc != null ? proc.setAdj : 0;
5602                }
5603            }
5604            infos[i] = new Debug.MemoryInfo();
5605            Debug.getMemoryInfo(pids[i], infos[i]);
5606            if (proc != null) {
5607                synchronized (this) {
5608                    if (proc.thread != null && proc.setAdj == oomAdj) {
5609                        // Record this for posterity if the process has been stable.
5610                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5611                                infos[i].getTotalUss(), false, proc.pkgList);
5612                    }
5613                }
5614            }
5615        }
5616        return infos;
5617    }
5618
5619    @Override
5620    public long[] getProcessPss(int[] pids) {
5621        enforceNotIsolatedCaller("getProcessPss");
5622        long[] pss = new long[pids.length];
5623        for (int i=pids.length-1; i>=0; i--) {
5624            ProcessRecord proc;
5625            int oomAdj;
5626            synchronized (this) {
5627                synchronized (mPidsSelfLocked) {
5628                    proc = mPidsSelfLocked.get(pids[i]);
5629                    oomAdj = proc != null ? proc.setAdj : 0;
5630                }
5631            }
5632            long[] tmpUss = new long[1];
5633            pss[i] = Debug.getPss(pids[i], tmpUss);
5634            if (proc != null) {
5635                synchronized (this) {
5636                    if (proc.thread != null && proc.setAdj == oomAdj) {
5637                        // Record this for posterity if the process has been stable.
5638                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5639                    }
5640                }
5641            }
5642        }
5643        return pss;
5644    }
5645
5646    @Override
5647    public void killApplicationProcess(String processName, int uid) {
5648        if (processName == null) {
5649            return;
5650        }
5651
5652        int callerUid = Binder.getCallingUid();
5653        // Only the system server can kill an application
5654        if (callerUid == Process.SYSTEM_UID) {
5655            synchronized (this) {
5656                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5657                if (app != null && app.thread != null) {
5658                    try {
5659                        app.thread.scheduleSuicide();
5660                    } catch (RemoteException e) {
5661                        // If the other end already died, then our work here is done.
5662                    }
5663                } else {
5664                    Slog.w(TAG, "Process/uid not found attempting kill of "
5665                            + processName + " / " + uid);
5666                }
5667            }
5668        } else {
5669            throw new SecurityException(callerUid + " cannot kill app process: " +
5670                    processName);
5671        }
5672    }
5673
5674    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5675        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5676                false, true, false, false, UserHandle.getUserId(uid), reason);
5677        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5678                Uri.fromParts("package", packageName, null));
5679        if (!mProcessesReady) {
5680            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5681                    | Intent.FLAG_RECEIVER_FOREGROUND);
5682        }
5683        intent.putExtra(Intent.EXTRA_UID, uid);
5684        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5685        broadcastIntentLocked(null, null, intent,
5686                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5687                false, false,
5688                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5689    }
5690
5691    private void forceStopUserLocked(int userId, String reason) {
5692        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5693        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5694        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5695                | Intent.FLAG_RECEIVER_FOREGROUND);
5696        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5697        broadcastIntentLocked(null, null, intent,
5698                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5699                false, false,
5700                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5701    }
5702
5703    private final boolean killPackageProcessesLocked(String packageName, int appId,
5704            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5705            boolean doit, boolean evenPersistent, String reason) {
5706        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5707
5708        // Remove all processes this package may have touched: all with the
5709        // same UID (except for the system or root user), and all whose name
5710        // matches the package name.
5711        final int NP = mProcessNames.getMap().size();
5712        for (int ip=0; ip<NP; ip++) {
5713            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5714            final int NA = apps.size();
5715            for (int ia=0; ia<NA; ia++) {
5716                ProcessRecord app = apps.valueAt(ia);
5717                if (app.persistent && !evenPersistent) {
5718                    // we don't kill persistent processes
5719                    continue;
5720                }
5721                if (app.removed) {
5722                    if (doit) {
5723                        procs.add(app);
5724                    }
5725                    continue;
5726                }
5727
5728                // Skip process if it doesn't meet our oom adj requirement.
5729                if (app.setAdj < minOomAdj) {
5730                    continue;
5731                }
5732
5733                // If no package is specified, we call all processes under the
5734                // give user id.
5735                if (packageName == null) {
5736                    if (app.userId != userId) {
5737                        continue;
5738                    }
5739                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5740                        continue;
5741                    }
5742                // Package has been specified, we want to hit all processes
5743                // that match it.  We need to qualify this by the processes
5744                // that are running under the specified app and user ID.
5745                } else {
5746                    final boolean isDep = app.pkgDeps != null
5747                            && app.pkgDeps.contains(packageName);
5748                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5749                        continue;
5750                    }
5751                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5752                        continue;
5753                    }
5754                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5755                        continue;
5756                    }
5757                }
5758
5759                // Process has passed all conditions, kill it!
5760                if (!doit) {
5761                    return true;
5762                }
5763                app.removed = true;
5764                procs.add(app);
5765            }
5766        }
5767
5768        int N = procs.size();
5769        for (int i=0; i<N; i++) {
5770            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5771        }
5772        updateOomAdjLocked();
5773        return N > 0;
5774    }
5775
5776    private final boolean forceStopPackageLocked(String name, int appId,
5777            boolean callerWillRestart, boolean purgeCache, boolean doit,
5778            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5779        int i;
5780        int N;
5781
5782        if (userId == UserHandle.USER_ALL && name == null) {
5783            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5784        }
5785
5786        if (appId < 0 && name != null) {
5787            try {
5788                appId = UserHandle.getAppId(
5789                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5790            } catch (RemoteException e) {
5791            }
5792        }
5793
5794        if (doit) {
5795            if (name != null) {
5796                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5797                        + " user=" + userId + ": " + reason);
5798            } else {
5799                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5800            }
5801
5802            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5803            for (int ip=pmap.size()-1; ip>=0; ip--) {
5804                SparseArray<Long> ba = pmap.valueAt(ip);
5805                for (i=ba.size()-1; i>=0; i--) {
5806                    boolean remove = false;
5807                    final int entUid = ba.keyAt(i);
5808                    if (name != null) {
5809                        if (userId == UserHandle.USER_ALL) {
5810                            if (UserHandle.getAppId(entUid) == appId) {
5811                                remove = true;
5812                            }
5813                        } else {
5814                            if (entUid == UserHandle.getUid(userId, appId)) {
5815                                remove = true;
5816                            }
5817                        }
5818                    } else if (UserHandle.getUserId(entUid) == userId) {
5819                        remove = true;
5820                    }
5821                    if (remove) {
5822                        ba.removeAt(i);
5823                    }
5824                }
5825                if (ba.size() == 0) {
5826                    pmap.removeAt(ip);
5827                }
5828            }
5829        }
5830
5831        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5832                -100, callerWillRestart, true, doit, evenPersistent,
5833                name == null ? ("stop user " + userId) : ("stop " + name));
5834
5835        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5836            if (!doit) {
5837                return true;
5838            }
5839            didSomething = true;
5840        }
5841
5842        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5843            if (!doit) {
5844                return true;
5845            }
5846            didSomething = true;
5847        }
5848
5849        if (name == null) {
5850            // Remove all sticky broadcasts from this user.
5851            mStickyBroadcasts.remove(userId);
5852        }
5853
5854        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5855        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5856                userId, providers)) {
5857            if (!doit) {
5858                return true;
5859            }
5860            didSomething = true;
5861        }
5862        N = providers.size();
5863        for (i=0; i<N; i++) {
5864            removeDyingProviderLocked(null, providers.get(i), true);
5865        }
5866
5867        // Remove transient permissions granted from/to this package/user
5868        removeUriPermissionsForPackageLocked(name, userId, false);
5869
5870        if (name == null || uninstalling) {
5871            // Remove pending intents.  For now we only do this when force
5872            // stopping users, because we have some problems when doing this
5873            // for packages -- app widgets are not currently cleaned up for
5874            // such packages, so they can be left with bad pending intents.
5875            if (mIntentSenderRecords.size() > 0) {
5876                Iterator<WeakReference<PendingIntentRecord>> it
5877                        = mIntentSenderRecords.values().iterator();
5878                while (it.hasNext()) {
5879                    WeakReference<PendingIntentRecord> wpir = it.next();
5880                    if (wpir == null) {
5881                        it.remove();
5882                        continue;
5883                    }
5884                    PendingIntentRecord pir = wpir.get();
5885                    if (pir == null) {
5886                        it.remove();
5887                        continue;
5888                    }
5889                    if (name == null) {
5890                        // Stopping user, remove all objects for the user.
5891                        if (pir.key.userId != userId) {
5892                            // Not the same user, skip it.
5893                            continue;
5894                        }
5895                    } else {
5896                        if (UserHandle.getAppId(pir.uid) != appId) {
5897                            // Different app id, skip it.
5898                            continue;
5899                        }
5900                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5901                            // Different user, skip it.
5902                            continue;
5903                        }
5904                        if (!pir.key.packageName.equals(name)) {
5905                            // Different package, skip it.
5906                            continue;
5907                        }
5908                    }
5909                    if (!doit) {
5910                        return true;
5911                    }
5912                    didSomething = true;
5913                    it.remove();
5914                    pir.canceled = true;
5915                    if (pir.key.activity != null) {
5916                        pir.key.activity.pendingResults.remove(pir.ref);
5917                    }
5918                }
5919            }
5920        }
5921
5922        if (doit) {
5923            if (purgeCache && name != null) {
5924                AttributeCache ac = AttributeCache.instance();
5925                if (ac != null) {
5926                    ac.removePackage(name);
5927                }
5928            }
5929            if (mBooted) {
5930                mStackSupervisor.resumeTopActivitiesLocked();
5931                mStackSupervisor.scheduleIdleLocked();
5932            }
5933        }
5934
5935        return didSomething;
5936    }
5937
5938    private final boolean removeProcessLocked(ProcessRecord app,
5939            boolean callerWillRestart, boolean allowRestart, String reason) {
5940        final String name = app.processName;
5941        final int uid = app.uid;
5942        if (DEBUG_PROCESSES) Slog.d(
5943            TAG, "Force removing proc " + app.toShortString() + " (" + name
5944            + "/" + uid + ")");
5945
5946        mProcessNames.remove(name, uid);
5947        mIsolatedProcesses.remove(app.uid);
5948        if (mHeavyWeightProcess == app) {
5949            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5950                    mHeavyWeightProcess.userId, 0));
5951            mHeavyWeightProcess = null;
5952        }
5953        boolean needRestart = false;
5954        if (app.pid > 0 && app.pid != MY_PID) {
5955            int pid = app.pid;
5956            synchronized (mPidsSelfLocked) {
5957                mPidsSelfLocked.remove(pid);
5958                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5959            }
5960            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5961            if (app.isolated) {
5962                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5963            }
5964            app.kill(reason, true);
5965            handleAppDiedLocked(app, true, allowRestart);
5966            removeLruProcessLocked(app);
5967
5968            if (app.persistent && !app.isolated) {
5969                if (!callerWillRestart) {
5970                    addAppLocked(app.info, false, null /* ABI override */);
5971                } else {
5972                    needRestart = true;
5973                }
5974            }
5975        } else {
5976            mRemovedProcesses.add(app);
5977        }
5978
5979        return needRestart;
5980    }
5981
5982    private final void processStartTimedOutLocked(ProcessRecord app) {
5983        final int pid = app.pid;
5984        boolean gone = false;
5985        synchronized (mPidsSelfLocked) {
5986            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5987            if (knownApp != null && knownApp.thread == null) {
5988                mPidsSelfLocked.remove(pid);
5989                gone = true;
5990            }
5991        }
5992
5993        if (gone) {
5994            Slog.w(TAG, "Process " + app + " failed to attach");
5995            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5996                    pid, app.uid, app.processName);
5997            mProcessNames.remove(app.processName, app.uid);
5998            mIsolatedProcesses.remove(app.uid);
5999            if (mHeavyWeightProcess == app) {
6000                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6001                        mHeavyWeightProcess.userId, 0));
6002                mHeavyWeightProcess = null;
6003            }
6004            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6005            if (app.isolated) {
6006                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6007            }
6008            // Take care of any launching providers waiting for this process.
6009            checkAppInLaunchingProvidersLocked(app, true);
6010            // Take care of any services that are waiting for the process.
6011            mServices.processStartTimedOutLocked(app);
6012            app.kill("start timeout", true);
6013            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6014                Slog.w(TAG, "Unattached app died before backup, skipping");
6015                try {
6016                    IBackupManager bm = IBackupManager.Stub.asInterface(
6017                            ServiceManager.getService(Context.BACKUP_SERVICE));
6018                    bm.agentDisconnected(app.info.packageName);
6019                } catch (RemoteException e) {
6020                    // Can't happen; the backup manager is local
6021                }
6022            }
6023            if (isPendingBroadcastProcessLocked(pid)) {
6024                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6025                skipPendingBroadcastLocked(pid);
6026            }
6027        } else {
6028            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6029        }
6030    }
6031
6032    private final boolean attachApplicationLocked(IApplicationThread thread,
6033            int pid) {
6034
6035        // Find the application record that is being attached...  either via
6036        // the pid if we are running in multiple processes, or just pull the
6037        // next app record if we are emulating process with anonymous threads.
6038        ProcessRecord app;
6039        if (pid != MY_PID && pid >= 0) {
6040            synchronized (mPidsSelfLocked) {
6041                app = mPidsSelfLocked.get(pid);
6042            }
6043        } else {
6044            app = null;
6045        }
6046
6047        if (app == null) {
6048            Slog.w(TAG, "No pending application record for pid " + pid
6049                    + " (IApplicationThread " + thread + "); dropping process");
6050            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6051            if (pid > 0 && pid != MY_PID) {
6052                Process.killProcessQuiet(pid);
6053                //TODO: Process.killProcessGroup(app.info.uid, pid);
6054            } else {
6055                try {
6056                    thread.scheduleExit();
6057                } catch (Exception e) {
6058                    // Ignore exceptions.
6059                }
6060            }
6061            return false;
6062        }
6063
6064        // If this application record is still attached to a previous
6065        // process, clean it up now.
6066        if (app.thread != null) {
6067            handleAppDiedLocked(app, true, true);
6068        }
6069
6070        // Tell the process all about itself.
6071
6072        if (localLOGV) Slog.v(
6073                TAG, "Binding process pid " + pid + " to record " + app);
6074
6075        final String processName = app.processName;
6076        try {
6077            AppDeathRecipient adr = new AppDeathRecipient(
6078                    app, pid, thread);
6079            thread.asBinder().linkToDeath(adr, 0);
6080            app.deathRecipient = adr;
6081        } catch (RemoteException e) {
6082            app.resetPackageList(mProcessStats);
6083            startProcessLocked(app, "link fail", processName);
6084            return false;
6085        }
6086
6087        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6088
6089        app.makeActive(thread, mProcessStats);
6090        app.curAdj = app.setAdj = -100;
6091        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6092        app.forcingToForeground = null;
6093        updateProcessForegroundLocked(app, false, false);
6094        app.hasShownUi = false;
6095        app.debugging = false;
6096        app.cached = false;
6097
6098        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6099
6100        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6101        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6102
6103        if (!normalMode) {
6104            Slog.i(TAG, "Launching preboot mode app: " + app);
6105        }
6106
6107        if (localLOGV) Slog.v(
6108            TAG, "New app record " + app
6109            + " thread=" + thread.asBinder() + " pid=" + pid);
6110        try {
6111            int testMode = IApplicationThread.DEBUG_OFF;
6112            if (mDebugApp != null && mDebugApp.equals(processName)) {
6113                testMode = mWaitForDebugger
6114                    ? IApplicationThread.DEBUG_WAIT
6115                    : IApplicationThread.DEBUG_ON;
6116                app.debugging = true;
6117                if (mDebugTransient) {
6118                    mDebugApp = mOrigDebugApp;
6119                    mWaitForDebugger = mOrigWaitForDebugger;
6120                }
6121            }
6122            String profileFile = app.instrumentationProfileFile;
6123            ParcelFileDescriptor profileFd = null;
6124            int samplingInterval = 0;
6125            boolean profileAutoStop = false;
6126            if (mProfileApp != null && mProfileApp.equals(processName)) {
6127                mProfileProc = app;
6128                profileFile = mProfileFile;
6129                profileFd = mProfileFd;
6130                samplingInterval = mSamplingInterval;
6131                profileAutoStop = mAutoStopProfiler;
6132            }
6133            boolean enableOpenGlTrace = false;
6134            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6135                enableOpenGlTrace = true;
6136                mOpenGlTraceApp = null;
6137            }
6138
6139            // If the app is being launched for restore or full backup, set it up specially
6140            boolean isRestrictedBackupMode = false;
6141            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6142                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6143                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6144                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6145            }
6146
6147            ensurePackageDexOpt(app.instrumentationInfo != null
6148                    ? app.instrumentationInfo.packageName
6149                    : app.info.packageName);
6150            if (app.instrumentationClass != null) {
6151                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6152            }
6153            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6154                    + processName + " with config " + mConfiguration);
6155            ApplicationInfo appInfo = app.instrumentationInfo != null
6156                    ? app.instrumentationInfo : app.info;
6157            app.compat = compatibilityInfoForPackageLocked(appInfo);
6158            if (profileFd != null) {
6159                profileFd = profileFd.dup();
6160            }
6161            ProfilerInfo profilerInfo = profileFile == null ? null
6162                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6163            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6164                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6165                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6166                    isRestrictedBackupMode || !normalMode, app.persistent,
6167                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6168                    mCoreSettingsObserver.getCoreSettingsLocked());
6169            updateLruProcessLocked(app, false, null);
6170            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6171        } catch (Exception e) {
6172            // todo: Yikes!  What should we do?  For now we will try to
6173            // start another process, but that could easily get us in
6174            // an infinite loop of restarting processes...
6175            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6176
6177            app.resetPackageList(mProcessStats);
6178            app.unlinkDeathRecipient();
6179            startProcessLocked(app, "bind fail", processName);
6180            return false;
6181        }
6182
6183        // Remove this record from the list of starting applications.
6184        mPersistentStartingProcesses.remove(app);
6185        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6186                "Attach application locked removing on hold: " + app);
6187        mProcessesOnHold.remove(app);
6188
6189        boolean badApp = false;
6190        boolean didSomething = false;
6191
6192        // See if the top visible activity is waiting to run in this process...
6193        if (normalMode) {
6194            try {
6195                if (mStackSupervisor.attachApplicationLocked(app)) {
6196                    didSomething = true;
6197                }
6198            } catch (Exception e) {
6199                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6200                badApp = true;
6201            }
6202        }
6203
6204        // Find any services that should be running in this process...
6205        if (!badApp) {
6206            try {
6207                didSomething |= mServices.attachApplicationLocked(app, processName);
6208            } catch (Exception e) {
6209                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6210                badApp = true;
6211            }
6212        }
6213
6214        // Check if a next-broadcast receiver is in this process...
6215        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6216            try {
6217                didSomething |= sendPendingBroadcastsLocked(app);
6218            } catch (Exception e) {
6219                // If the app died trying to launch the receiver we declare it 'bad'
6220                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6221                badApp = true;
6222            }
6223        }
6224
6225        // Check whether the next backup agent is in this process...
6226        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6227            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6228            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6229            try {
6230                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6231                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6232                        mBackupTarget.backupMode);
6233            } catch (Exception e) {
6234                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6235                badApp = true;
6236            }
6237        }
6238
6239        if (badApp) {
6240            app.kill("error during init", true);
6241            handleAppDiedLocked(app, false, true);
6242            return false;
6243        }
6244
6245        if (!didSomething) {
6246            updateOomAdjLocked();
6247        }
6248
6249        return true;
6250    }
6251
6252    @Override
6253    public final void attachApplication(IApplicationThread thread) {
6254        synchronized (this) {
6255            int callingPid = Binder.getCallingPid();
6256            final long origId = Binder.clearCallingIdentity();
6257            attachApplicationLocked(thread, callingPid);
6258            Binder.restoreCallingIdentity(origId);
6259        }
6260    }
6261
6262    @Override
6263    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6264        final long origId = Binder.clearCallingIdentity();
6265        synchronized (this) {
6266            ActivityStack stack = ActivityRecord.getStackLocked(token);
6267            if (stack != null) {
6268                ActivityRecord r =
6269                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6270                if (stopProfiling) {
6271                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6272                        try {
6273                            mProfileFd.close();
6274                        } catch (IOException e) {
6275                        }
6276                        clearProfilerLocked();
6277                    }
6278                }
6279            }
6280        }
6281        Binder.restoreCallingIdentity(origId);
6282    }
6283
6284    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6285        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6286                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6287    }
6288
6289    void enableScreenAfterBoot() {
6290        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6291                SystemClock.uptimeMillis());
6292        mWindowManager.enableScreenAfterBoot();
6293
6294        synchronized (this) {
6295            updateEventDispatchingLocked();
6296        }
6297    }
6298
6299    @Override
6300    public void showBootMessage(final CharSequence msg, final boolean always) {
6301        enforceNotIsolatedCaller("showBootMessage");
6302        mWindowManager.showBootMessage(msg, always);
6303    }
6304
6305    @Override
6306    public void keyguardWaitingForActivityDrawn() {
6307        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6308        final long token = Binder.clearCallingIdentity();
6309        try {
6310            synchronized (this) {
6311                if (DEBUG_LOCKSCREEN) logLockScreen("");
6312                mWindowManager.keyguardWaitingForActivityDrawn();
6313                if (mLockScreenShown) {
6314                    mLockScreenShown = false;
6315                    comeOutOfSleepIfNeededLocked();
6316                }
6317            }
6318        } finally {
6319            Binder.restoreCallingIdentity(token);
6320        }
6321    }
6322
6323    final void finishBooting() {
6324        synchronized (this) {
6325            if (!mBootAnimationComplete) {
6326                mCallFinishBooting = true;
6327                return;
6328            }
6329            mCallFinishBooting = false;
6330        }
6331
6332        // Register receivers to handle package update events
6333        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6334
6335        // Let system services know.
6336        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6337
6338        synchronized (this) {
6339            // Ensure that any processes we had put on hold are now started
6340            // up.
6341            final int NP = mProcessesOnHold.size();
6342            if (NP > 0) {
6343                ArrayList<ProcessRecord> procs =
6344                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6345                for (int ip=0; ip<NP; ip++) {
6346                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6347                            + procs.get(ip));
6348                    startProcessLocked(procs.get(ip), "on-hold", null);
6349                }
6350            }
6351
6352            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6353                // Start looking for apps that are abusing wake locks.
6354                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6355                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6356                // Tell anyone interested that we are done booting!
6357                SystemProperties.set("sys.boot_completed", "1");
6358
6359                // And trigger dev.bootcomplete if we are not showing encryption progress
6360                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6361                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6362                    SystemProperties.set("dev.bootcomplete", "1");
6363                }
6364                for (int i=0; i<mStartedUsers.size(); i++) {
6365                    UserStartedState uss = mStartedUsers.valueAt(i);
6366                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6367                        uss.mState = UserStartedState.STATE_RUNNING;
6368                        final int userId = mStartedUsers.keyAt(i);
6369                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6370                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6371                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6372                        broadcastIntentLocked(null, null, intent, null,
6373                                new IIntentReceiver.Stub() {
6374                                    @Override
6375                                    public void performReceive(Intent intent, int resultCode,
6376                                            String data, Bundle extras, boolean ordered,
6377                                            boolean sticky, int sendingUser) {
6378                                        synchronized (ActivityManagerService.this) {
6379                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6380                                                    true, false);
6381                                        }
6382                                    }
6383                                },
6384                                0, null, null,
6385                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6386                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6387                                userId);
6388                    }
6389                }
6390                scheduleStartProfilesLocked();
6391            }
6392        }
6393    }
6394
6395    @Override
6396    public void bootAnimationComplete() {
6397        final boolean callFinishBooting;
6398        synchronized (this) {
6399            callFinishBooting = mCallFinishBooting;
6400            mBootAnimationComplete = true;
6401        }
6402        if (callFinishBooting) {
6403            finishBooting();
6404        }
6405    }
6406
6407    final void ensureBootCompleted() {
6408        boolean booting;
6409        boolean enableScreen;
6410        synchronized (this) {
6411            booting = mBooting;
6412            mBooting = false;
6413            enableScreen = !mBooted;
6414            mBooted = true;
6415        }
6416
6417        if (booting) {
6418            finishBooting();
6419        }
6420
6421        if (enableScreen) {
6422            enableScreenAfterBoot();
6423        }
6424    }
6425
6426    @Override
6427    public final void activityResumed(IBinder token) {
6428        final long origId = Binder.clearCallingIdentity();
6429        synchronized(this) {
6430            ActivityStack stack = ActivityRecord.getStackLocked(token);
6431            if (stack != null) {
6432                ActivityRecord.activityResumedLocked(token);
6433            }
6434        }
6435        Binder.restoreCallingIdentity(origId);
6436    }
6437
6438    @Override
6439    public final void activityPaused(IBinder token) {
6440        final long origId = Binder.clearCallingIdentity();
6441        synchronized(this) {
6442            ActivityStack stack = ActivityRecord.getStackLocked(token);
6443            if (stack != null) {
6444                stack.activityPausedLocked(token, false);
6445            }
6446        }
6447        Binder.restoreCallingIdentity(origId);
6448    }
6449
6450    @Override
6451    public final void activityStopped(IBinder token, Bundle icicle,
6452            PersistableBundle persistentState, CharSequence description) {
6453        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6454
6455        // Refuse possible leaked file descriptors
6456        if (icicle != null && icicle.hasFileDescriptors()) {
6457            throw new IllegalArgumentException("File descriptors passed in Bundle");
6458        }
6459
6460        final long origId = Binder.clearCallingIdentity();
6461
6462        synchronized (this) {
6463            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6464            if (r != null) {
6465                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6466            }
6467        }
6468
6469        trimApplications();
6470
6471        Binder.restoreCallingIdentity(origId);
6472    }
6473
6474    @Override
6475    public final void activityDestroyed(IBinder token) {
6476        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6477        synchronized (this) {
6478            ActivityStack stack = ActivityRecord.getStackLocked(token);
6479            if (stack != null) {
6480                stack.activityDestroyedLocked(token);
6481            }
6482        }
6483    }
6484
6485    @Override
6486    public final void backgroundResourcesReleased(IBinder token) {
6487        final long origId = Binder.clearCallingIdentity();
6488        try {
6489            synchronized (this) {
6490                ActivityStack stack = ActivityRecord.getStackLocked(token);
6491                if (stack != null) {
6492                    stack.backgroundResourcesReleased(token);
6493                }
6494            }
6495        } finally {
6496            Binder.restoreCallingIdentity(origId);
6497        }
6498    }
6499
6500    @Override
6501    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6502        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6503    }
6504
6505    @Override
6506    public final void notifyEnterAnimationComplete(IBinder token) {
6507        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6508    }
6509
6510    @Override
6511    public String getCallingPackage(IBinder token) {
6512        synchronized (this) {
6513            ActivityRecord r = getCallingRecordLocked(token);
6514            return r != null ? r.info.packageName : null;
6515        }
6516    }
6517
6518    @Override
6519    public ComponentName getCallingActivity(IBinder token) {
6520        synchronized (this) {
6521            ActivityRecord r = getCallingRecordLocked(token);
6522            return r != null ? r.intent.getComponent() : null;
6523        }
6524    }
6525
6526    private ActivityRecord getCallingRecordLocked(IBinder token) {
6527        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6528        if (r == null) {
6529            return null;
6530        }
6531        return r.resultTo;
6532    }
6533
6534    @Override
6535    public ComponentName getActivityClassForToken(IBinder token) {
6536        synchronized(this) {
6537            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6538            if (r == null) {
6539                return null;
6540            }
6541            return r.intent.getComponent();
6542        }
6543    }
6544
6545    @Override
6546    public String getPackageForToken(IBinder token) {
6547        synchronized(this) {
6548            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6549            if (r == null) {
6550                return null;
6551            }
6552            return r.packageName;
6553        }
6554    }
6555
6556    @Override
6557    public IIntentSender getIntentSender(int type,
6558            String packageName, IBinder token, String resultWho,
6559            int requestCode, Intent[] intents, String[] resolvedTypes,
6560            int flags, Bundle options, int userId) {
6561        enforceNotIsolatedCaller("getIntentSender");
6562        // Refuse possible leaked file descriptors
6563        if (intents != null) {
6564            if (intents.length < 1) {
6565                throw new IllegalArgumentException("Intents array length must be >= 1");
6566            }
6567            for (int i=0; i<intents.length; i++) {
6568                Intent intent = intents[i];
6569                if (intent != null) {
6570                    if (intent.hasFileDescriptors()) {
6571                        throw new IllegalArgumentException("File descriptors passed in Intent");
6572                    }
6573                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6574                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6575                        throw new IllegalArgumentException(
6576                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6577                    }
6578                    intents[i] = new Intent(intent);
6579                }
6580            }
6581            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6582                throw new IllegalArgumentException(
6583                        "Intent array length does not match resolvedTypes length");
6584            }
6585        }
6586        if (options != null) {
6587            if (options.hasFileDescriptors()) {
6588                throw new IllegalArgumentException("File descriptors passed in options");
6589            }
6590        }
6591
6592        synchronized(this) {
6593            int callingUid = Binder.getCallingUid();
6594            int origUserId = userId;
6595            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6596                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6597                    ALLOW_NON_FULL, "getIntentSender", null);
6598            if (origUserId == UserHandle.USER_CURRENT) {
6599                // We don't want to evaluate this until the pending intent is
6600                // actually executed.  However, we do want to always do the
6601                // security checking for it above.
6602                userId = UserHandle.USER_CURRENT;
6603            }
6604            try {
6605                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6606                    int uid = AppGlobals.getPackageManager()
6607                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6608                    if (!UserHandle.isSameApp(callingUid, uid)) {
6609                        String msg = "Permission Denial: getIntentSender() from pid="
6610                            + Binder.getCallingPid()
6611                            + ", uid=" + Binder.getCallingUid()
6612                            + ", (need uid=" + uid + ")"
6613                            + " is not allowed to send as package " + packageName;
6614                        Slog.w(TAG, msg);
6615                        throw new SecurityException(msg);
6616                    }
6617                }
6618
6619                return getIntentSenderLocked(type, packageName, callingUid, userId,
6620                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6621
6622            } catch (RemoteException e) {
6623                throw new SecurityException(e);
6624            }
6625        }
6626    }
6627
6628    IIntentSender getIntentSenderLocked(int type, String packageName,
6629            int callingUid, int userId, IBinder token, String resultWho,
6630            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6631            Bundle options) {
6632        if (DEBUG_MU)
6633            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6634        ActivityRecord activity = null;
6635        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6636            activity = ActivityRecord.isInStackLocked(token);
6637            if (activity == null) {
6638                return null;
6639            }
6640            if (activity.finishing) {
6641                return null;
6642            }
6643        }
6644
6645        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6646        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6647        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6648        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6649                |PendingIntent.FLAG_UPDATE_CURRENT);
6650
6651        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6652                type, packageName, activity, resultWho,
6653                requestCode, intents, resolvedTypes, flags, options, userId);
6654        WeakReference<PendingIntentRecord> ref;
6655        ref = mIntentSenderRecords.get(key);
6656        PendingIntentRecord rec = ref != null ? ref.get() : null;
6657        if (rec != null) {
6658            if (!cancelCurrent) {
6659                if (updateCurrent) {
6660                    if (rec.key.requestIntent != null) {
6661                        rec.key.requestIntent.replaceExtras(intents != null ?
6662                                intents[intents.length - 1] : null);
6663                    }
6664                    if (intents != null) {
6665                        intents[intents.length-1] = rec.key.requestIntent;
6666                        rec.key.allIntents = intents;
6667                        rec.key.allResolvedTypes = resolvedTypes;
6668                    } else {
6669                        rec.key.allIntents = null;
6670                        rec.key.allResolvedTypes = null;
6671                    }
6672                }
6673                return rec;
6674            }
6675            rec.canceled = true;
6676            mIntentSenderRecords.remove(key);
6677        }
6678        if (noCreate) {
6679            return rec;
6680        }
6681        rec = new PendingIntentRecord(this, key, callingUid);
6682        mIntentSenderRecords.put(key, rec.ref);
6683        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6684            if (activity.pendingResults == null) {
6685                activity.pendingResults
6686                        = new HashSet<WeakReference<PendingIntentRecord>>();
6687            }
6688            activity.pendingResults.add(rec.ref);
6689        }
6690        return rec;
6691    }
6692
6693    @Override
6694    public void cancelIntentSender(IIntentSender sender) {
6695        if (!(sender instanceof PendingIntentRecord)) {
6696            return;
6697        }
6698        synchronized(this) {
6699            PendingIntentRecord rec = (PendingIntentRecord)sender;
6700            try {
6701                int uid = AppGlobals.getPackageManager()
6702                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6703                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6704                    String msg = "Permission Denial: cancelIntentSender() from pid="
6705                        + Binder.getCallingPid()
6706                        + ", uid=" + Binder.getCallingUid()
6707                        + " is not allowed to cancel packges "
6708                        + rec.key.packageName;
6709                    Slog.w(TAG, msg);
6710                    throw new SecurityException(msg);
6711                }
6712            } catch (RemoteException e) {
6713                throw new SecurityException(e);
6714            }
6715            cancelIntentSenderLocked(rec, true);
6716        }
6717    }
6718
6719    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6720        rec.canceled = true;
6721        mIntentSenderRecords.remove(rec.key);
6722        if (cleanActivity && rec.key.activity != null) {
6723            rec.key.activity.pendingResults.remove(rec.ref);
6724        }
6725    }
6726
6727    @Override
6728    public String getPackageForIntentSender(IIntentSender pendingResult) {
6729        if (!(pendingResult instanceof PendingIntentRecord)) {
6730            return null;
6731        }
6732        try {
6733            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6734            return res.key.packageName;
6735        } catch (ClassCastException e) {
6736        }
6737        return null;
6738    }
6739
6740    @Override
6741    public int getUidForIntentSender(IIntentSender sender) {
6742        if (sender instanceof PendingIntentRecord) {
6743            try {
6744                PendingIntentRecord res = (PendingIntentRecord)sender;
6745                return res.uid;
6746            } catch (ClassCastException e) {
6747            }
6748        }
6749        return -1;
6750    }
6751
6752    @Override
6753    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6754        if (!(pendingResult instanceof PendingIntentRecord)) {
6755            return false;
6756        }
6757        try {
6758            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6759            if (res.key.allIntents == null) {
6760                return false;
6761            }
6762            for (int i=0; i<res.key.allIntents.length; i++) {
6763                Intent intent = res.key.allIntents[i];
6764                if (intent.getPackage() != null && intent.getComponent() != null) {
6765                    return false;
6766                }
6767            }
6768            return true;
6769        } catch (ClassCastException e) {
6770        }
6771        return false;
6772    }
6773
6774    @Override
6775    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6776        if (!(pendingResult instanceof PendingIntentRecord)) {
6777            return false;
6778        }
6779        try {
6780            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6781            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6782                return true;
6783            }
6784            return false;
6785        } catch (ClassCastException e) {
6786        }
6787        return false;
6788    }
6789
6790    @Override
6791    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6792        if (!(pendingResult instanceof PendingIntentRecord)) {
6793            return null;
6794        }
6795        try {
6796            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6797            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6798        } catch (ClassCastException e) {
6799        }
6800        return null;
6801    }
6802
6803    @Override
6804    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6805        if (!(pendingResult instanceof PendingIntentRecord)) {
6806            return null;
6807        }
6808        try {
6809            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6810            Intent intent = res.key.requestIntent;
6811            if (intent != null) {
6812                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6813                        || res.lastTagPrefix.equals(prefix))) {
6814                    return res.lastTag;
6815                }
6816                res.lastTagPrefix = prefix;
6817                StringBuilder sb = new StringBuilder(128);
6818                if (prefix != null) {
6819                    sb.append(prefix);
6820                }
6821                if (intent.getAction() != null) {
6822                    sb.append(intent.getAction());
6823                } else if (intent.getComponent() != null) {
6824                    intent.getComponent().appendShortString(sb);
6825                } else {
6826                    sb.append("?");
6827                }
6828                return res.lastTag = sb.toString();
6829            }
6830        } catch (ClassCastException e) {
6831        }
6832        return null;
6833    }
6834
6835    @Override
6836    public void setProcessLimit(int max) {
6837        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6838                "setProcessLimit()");
6839        synchronized (this) {
6840            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6841            mProcessLimitOverride = max;
6842        }
6843        trimApplications();
6844    }
6845
6846    @Override
6847    public int getProcessLimit() {
6848        synchronized (this) {
6849            return mProcessLimitOverride;
6850        }
6851    }
6852
6853    void foregroundTokenDied(ForegroundToken token) {
6854        synchronized (ActivityManagerService.this) {
6855            synchronized (mPidsSelfLocked) {
6856                ForegroundToken cur
6857                    = mForegroundProcesses.get(token.pid);
6858                if (cur != token) {
6859                    return;
6860                }
6861                mForegroundProcesses.remove(token.pid);
6862                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6863                if (pr == null) {
6864                    return;
6865                }
6866                pr.forcingToForeground = null;
6867                updateProcessForegroundLocked(pr, false, false);
6868            }
6869            updateOomAdjLocked();
6870        }
6871    }
6872
6873    @Override
6874    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6875        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6876                "setProcessForeground()");
6877        synchronized(this) {
6878            boolean changed = false;
6879
6880            synchronized (mPidsSelfLocked) {
6881                ProcessRecord pr = mPidsSelfLocked.get(pid);
6882                if (pr == null && isForeground) {
6883                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6884                    return;
6885                }
6886                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6887                if (oldToken != null) {
6888                    oldToken.token.unlinkToDeath(oldToken, 0);
6889                    mForegroundProcesses.remove(pid);
6890                    if (pr != null) {
6891                        pr.forcingToForeground = null;
6892                    }
6893                    changed = true;
6894                }
6895                if (isForeground && token != null) {
6896                    ForegroundToken newToken = new ForegroundToken() {
6897                        @Override
6898                        public void binderDied() {
6899                            foregroundTokenDied(this);
6900                        }
6901                    };
6902                    newToken.pid = pid;
6903                    newToken.token = token;
6904                    try {
6905                        token.linkToDeath(newToken, 0);
6906                        mForegroundProcesses.put(pid, newToken);
6907                        pr.forcingToForeground = token;
6908                        changed = true;
6909                    } catch (RemoteException e) {
6910                        // If the process died while doing this, we will later
6911                        // do the cleanup with the process death link.
6912                    }
6913                }
6914            }
6915
6916            if (changed) {
6917                updateOomAdjLocked();
6918            }
6919        }
6920    }
6921
6922    // =========================================================
6923    // PERMISSIONS
6924    // =========================================================
6925
6926    static class PermissionController extends IPermissionController.Stub {
6927        ActivityManagerService mActivityManagerService;
6928        PermissionController(ActivityManagerService activityManagerService) {
6929            mActivityManagerService = activityManagerService;
6930        }
6931
6932        @Override
6933        public boolean checkPermission(String permission, int pid, int uid) {
6934            return mActivityManagerService.checkPermission(permission, pid,
6935                    uid) == PackageManager.PERMISSION_GRANTED;
6936        }
6937    }
6938
6939    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6940        @Override
6941        public int checkComponentPermission(String permission, int pid, int uid,
6942                int owningUid, boolean exported) {
6943            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6944                    owningUid, exported);
6945        }
6946
6947        @Override
6948        public Object getAMSLock() {
6949            return ActivityManagerService.this;
6950        }
6951    }
6952
6953    /**
6954     * This can be called with or without the global lock held.
6955     */
6956    int checkComponentPermission(String permission, int pid, int uid,
6957            int owningUid, boolean exported) {
6958        // We might be performing an operation on behalf of an indirect binder
6959        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6960        // client identity accordingly before proceeding.
6961        Identity tlsIdentity = sCallerIdentity.get();
6962        if (tlsIdentity != null) {
6963            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6964                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6965            uid = tlsIdentity.uid;
6966            pid = tlsIdentity.pid;
6967        }
6968
6969        if (pid == MY_PID) {
6970            return PackageManager.PERMISSION_GRANTED;
6971        }
6972
6973        return ActivityManager.checkComponentPermission(permission, uid,
6974                owningUid, exported);
6975    }
6976
6977    /**
6978     * As the only public entry point for permissions checking, this method
6979     * can enforce the semantic that requesting a check on a null global
6980     * permission is automatically denied.  (Internally a null permission
6981     * string is used when calling {@link #checkComponentPermission} in cases
6982     * when only uid-based security is needed.)
6983     *
6984     * This can be called with or without the global lock held.
6985     */
6986    @Override
6987    public int checkPermission(String permission, int pid, int uid) {
6988        if (permission == null) {
6989            return PackageManager.PERMISSION_DENIED;
6990        }
6991        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6992    }
6993
6994    /**
6995     * Binder IPC calls go through the public entry point.
6996     * This can be called with or without the global lock held.
6997     */
6998    int checkCallingPermission(String permission) {
6999        return checkPermission(permission,
7000                Binder.getCallingPid(),
7001                UserHandle.getAppId(Binder.getCallingUid()));
7002    }
7003
7004    /**
7005     * This can be called with or without the global lock held.
7006     */
7007    void enforceCallingPermission(String permission, String func) {
7008        if (checkCallingPermission(permission)
7009                == PackageManager.PERMISSION_GRANTED) {
7010            return;
7011        }
7012
7013        String msg = "Permission Denial: " + func + " from pid="
7014                + Binder.getCallingPid()
7015                + ", uid=" + Binder.getCallingUid()
7016                + " requires " + permission;
7017        Slog.w(TAG, msg);
7018        throw new SecurityException(msg);
7019    }
7020
7021    /**
7022     * Determine if UID is holding permissions required to access {@link Uri} in
7023     * the given {@link ProviderInfo}. Final permission checking is always done
7024     * in {@link ContentProvider}.
7025     */
7026    private final boolean checkHoldingPermissionsLocked(
7027            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7028        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7029                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7030        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7031            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7032                    != PERMISSION_GRANTED) {
7033                return false;
7034            }
7035        }
7036        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7037    }
7038
7039    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7040            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7041        if (pi.applicationInfo.uid == uid) {
7042            return true;
7043        } else if (!pi.exported) {
7044            return false;
7045        }
7046
7047        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7048        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7049        try {
7050            // check if target holds top-level <provider> permissions
7051            if (!readMet && pi.readPermission != null && considerUidPermissions
7052                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7053                readMet = true;
7054            }
7055            if (!writeMet && pi.writePermission != null && considerUidPermissions
7056                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7057                writeMet = true;
7058            }
7059
7060            // track if unprotected read/write is allowed; any denied
7061            // <path-permission> below removes this ability
7062            boolean allowDefaultRead = pi.readPermission == null;
7063            boolean allowDefaultWrite = pi.writePermission == null;
7064
7065            // check if target holds any <path-permission> that match uri
7066            final PathPermission[] pps = pi.pathPermissions;
7067            if (pps != null) {
7068                final String path = grantUri.uri.getPath();
7069                int i = pps.length;
7070                while (i > 0 && (!readMet || !writeMet)) {
7071                    i--;
7072                    PathPermission pp = pps[i];
7073                    if (pp.match(path)) {
7074                        if (!readMet) {
7075                            final String pprperm = pp.getReadPermission();
7076                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7077                                    + pprperm + " for " + pp.getPath()
7078                                    + ": match=" + pp.match(path)
7079                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7080                            if (pprperm != null) {
7081                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7082                                        == PERMISSION_GRANTED) {
7083                                    readMet = true;
7084                                } else {
7085                                    allowDefaultRead = false;
7086                                }
7087                            }
7088                        }
7089                        if (!writeMet) {
7090                            final String ppwperm = pp.getWritePermission();
7091                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7092                                    + ppwperm + " for " + pp.getPath()
7093                                    + ": match=" + pp.match(path)
7094                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7095                            if (ppwperm != null) {
7096                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7097                                        == PERMISSION_GRANTED) {
7098                                    writeMet = true;
7099                                } else {
7100                                    allowDefaultWrite = false;
7101                                }
7102                            }
7103                        }
7104                    }
7105                }
7106            }
7107
7108            // grant unprotected <provider> read/write, if not blocked by
7109            // <path-permission> above
7110            if (allowDefaultRead) readMet = true;
7111            if (allowDefaultWrite) writeMet = true;
7112
7113        } catch (RemoteException e) {
7114            return false;
7115        }
7116
7117        return readMet && writeMet;
7118    }
7119
7120    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7121        ProviderInfo pi = null;
7122        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7123        if (cpr != null) {
7124            pi = cpr.info;
7125        } else {
7126            try {
7127                pi = AppGlobals.getPackageManager().resolveContentProvider(
7128                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7129            } catch (RemoteException ex) {
7130            }
7131        }
7132        return pi;
7133    }
7134
7135    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7136        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7137        if (targetUris != null) {
7138            return targetUris.get(grantUri);
7139        }
7140        return null;
7141    }
7142
7143    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7144            String targetPkg, int targetUid, GrantUri grantUri) {
7145        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7146        if (targetUris == null) {
7147            targetUris = Maps.newArrayMap();
7148            mGrantedUriPermissions.put(targetUid, targetUris);
7149        }
7150
7151        UriPermission perm = targetUris.get(grantUri);
7152        if (perm == null) {
7153            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7154            targetUris.put(grantUri, perm);
7155        }
7156
7157        return perm;
7158    }
7159
7160    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7161            final int modeFlags) {
7162        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7163        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7164                : UriPermission.STRENGTH_OWNED;
7165
7166        // Root gets to do everything.
7167        if (uid == 0) {
7168            return true;
7169        }
7170
7171        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7172        if (perms == null) return false;
7173
7174        // First look for exact match
7175        final UriPermission exactPerm = perms.get(grantUri);
7176        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7177            return true;
7178        }
7179
7180        // No exact match, look for prefixes
7181        final int N = perms.size();
7182        for (int i = 0; i < N; i++) {
7183            final UriPermission perm = perms.valueAt(i);
7184            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7185                    && perm.getStrength(modeFlags) >= minStrength) {
7186                return true;
7187            }
7188        }
7189
7190        return false;
7191    }
7192
7193    /**
7194     * @param uri This uri must NOT contain an embedded userId.
7195     * @param userId The userId in which the uri is to be resolved.
7196     */
7197    @Override
7198    public int checkUriPermission(Uri uri, int pid, int uid,
7199            final int modeFlags, int userId) {
7200        enforceNotIsolatedCaller("checkUriPermission");
7201
7202        // Another redirected-binder-call permissions check as in
7203        // {@link checkComponentPermission}.
7204        Identity tlsIdentity = sCallerIdentity.get();
7205        if (tlsIdentity != null) {
7206            uid = tlsIdentity.uid;
7207            pid = tlsIdentity.pid;
7208        }
7209
7210        // Our own process gets to do everything.
7211        if (pid == MY_PID) {
7212            return PackageManager.PERMISSION_GRANTED;
7213        }
7214        synchronized (this) {
7215            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7216                    ? PackageManager.PERMISSION_GRANTED
7217                    : PackageManager.PERMISSION_DENIED;
7218        }
7219    }
7220
7221    /**
7222     * Check if the targetPkg can be granted permission to access uri by
7223     * the callingUid using the given modeFlags.  Throws a security exception
7224     * if callingUid is not allowed to do this.  Returns the uid of the target
7225     * if the URI permission grant should be performed; returns -1 if it is not
7226     * needed (for example targetPkg already has permission to access the URI).
7227     * If you already know the uid of the target, you can supply it in
7228     * lastTargetUid else set that to -1.
7229     */
7230    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7231            final int modeFlags, int lastTargetUid) {
7232        if (!Intent.isAccessUriMode(modeFlags)) {
7233            return -1;
7234        }
7235
7236        if (targetPkg != null) {
7237            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7238                    "Checking grant " + targetPkg + " permission to " + grantUri);
7239        }
7240
7241        final IPackageManager pm = AppGlobals.getPackageManager();
7242
7243        // If this is not a content: uri, we can't do anything with it.
7244        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7245            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7246                    "Can't grant URI permission for non-content URI: " + grantUri);
7247            return -1;
7248        }
7249
7250        final String authority = grantUri.uri.getAuthority();
7251        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7252        if (pi == null) {
7253            Slog.w(TAG, "No content provider found for permission check: " +
7254                    grantUri.uri.toSafeString());
7255            return -1;
7256        }
7257
7258        int targetUid = lastTargetUid;
7259        if (targetUid < 0 && targetPkg != null) {
7260            try {
7261                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7262                if (targetUid < 0) {
7263                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7264                            "Can't grant URI permission no uid for: " + targetPkg);
7265                    return -1;
7266                }
7267            } catch (RemoteException ex) {
7268                return -1;
7269            }
7270        }
7271
7272        if (targetUid >= 0) {
7273            // First...  does the target actually need this permission?
7274            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7275                // No need to grant the target this permission.
7276                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7277                        "Target " + targetPkg + " already has full permission to " + grantUri);
7278                return -1;
7279            }
7280        } else {
7281            // First...  there is no target package, so can anyone access it?
7282            boolean allowed = pi.exported;
7283            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7284                if (pi.readPermission != null) {
7285                    allowed = false;
7286                }
7287            }
7288            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7289                if (pi.writePermission != null) {
7290                    allowed = false;
7291                }
7292            }
7293            if (allowed) {
7294                return -1;
7295            }
7296        }
7297
7298        /* There is a special cross user grant if:
7299         * - The target is on another user.
7300         * - Apps on the current user can access the uri without any uid permissions.
7301         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7302         * grant uri permissions.
7303         */
7304        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7305                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7306                modeFlags, false /*without considering the uid permissions*/);
7307
7308        // Second...  is the provider allowing granting of URI permissions?
7309        if (!specialCrossUserGrant) {
7310            if (!pi.grantUriPermissions) {
7311                throw new SecurityException("Provider " + pi.packageName
7312                        + "/" + pi.name
7313                        + " does not allow granting of Uri permissions (uri "
7314                        + grantUri + ")");
7315            }
7316            if (pi.uriPermissionPatterns != null) {
7317                final int N = pi.uriPermissionPatterns.length;
7318                boolean allowed = false;
7319                for (int i=0; i<N; i++) {
7320                    if (pi.uriPermissionPatterns[i] != null
7321                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7322                        allowed = true;
7323                        break;
7324                    }
7325                }
7326                if (!allowed) {
7327                    throw new SecurityException("Provider " + pi.packageName
7328                            + "/" + pi.name
7329                            + " does not allow granting of permission to path of Uri "
7330                            + grantUri);
7331                }
7332            }
7333        }
7334
7335        // Third...  does the caller itself have permission to access
7336        // this uri?
7337        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7338            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7339                // Require they hold a strong enough Uri permission
7340                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7341                    throw new SecurityException("Uid " + callingUid
7342                            + " does not have permission to uri " + grantUri);
7343                }
7344            }
7345        }
7346        return targetUid;
7347    }
7348
7349    /**
7350     * @param uri This uri must NOT contain an embedded userId.
7351     * @param userId The userId in which the uri is to be resolved.
7352     */
7353    @Override
7354    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7355            final int modeFlags, int userId) {
7356        enforceNotIsolatedCaller("checkGrantUriPermission");
7357        synchronized(this) {
7358            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7359                    new GrantUri(userId, uri, false), modeFlags, -1);
7360        }
7361    }
7362
7363    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7364            final int modeFlags, UriPermissionOwner owner) {
7365        if (!Intent.isAccessUriMode(modeFlags)) {
7366            return;
7367        }
7368
7369        // So here we are: the caller has the assumed permission
7370        // to the uri, and the target doesn't.  Let's now give this to
7371        // the target.
7372
7373        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7374                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7375
7376        final String authority = grantUri.uri.getAuthority();
7377        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7378        if (pi == null) {
7379            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7380            return;
7381        }
7382
7383        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7384            grantUri.prefix = true;
7385        }
7386        final UriPermission perm = findOrCreateUriPermissionLocked(
7387                pi.packageName, targetPkg, targetUid, grantUri);
7388        perm.grantModes(modeFlags, owner);
7389    }
7390
7391    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7392            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7393        if (targetPkg == null) {
7394            throw new NullPointerException("targetPkg");
7395        }
7396        int targetUid;
7397        final IPackageManager pm = AppGlobals.getPackageManager();
7398        try {
7399            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7400        } catch (RemoteException ex) {
7401            return;
7402        }
7403
7404        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7405                targetUid);
7406        if (targetUid < 0) {
7407            return;
7408        }
7409
7410        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7411                owner);
7412    }
7413
7414    static class NeededUriGrants extends ArrayList<GrantUri> {
7415        final String targetPkg;
7416        final int targetUid;
7417        final int flags;
7418
7419        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7420            this.targetPkg = targetPkg;
7421            this.targetUid = targetUid;
7422            this.flags = flags;
7423        }
7424    }
7425
7426    /**
7427     * Like checkGrantUriPermissionLocked, but takes an Intent.
7428     */
7429    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7430            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7431        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7432                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7433                + " clip=" + (intent != null ? intent.getClipData() : null)
7434                + " from " + intent + "; flags=0x"
7435                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7436
7437        if (targetPkg == null) {
7438            throw new NullPointerException("targetPkg");
7439        }
7440
7441        if (intent == null) {
7442            return null;
7443        }
7444        Uri data = intent.getData();
7445        ClipData clip = intent.getClipData();
7446        if (data == null && clip == null) {
7447            return null;
7448        }
7449        // Default userId for uris in the intent (if they don't specify it themselves)
7450        int contentUserHint = intent.getContentUserHint();
7451        if (contentUserHint == UserHandle.USER_CURRENT) {
7452            contentUserHint = UserHandle.getUserId(callingUid);
7453        }
7454        final IPackageManager pm = AppGlobals.getPackageManager();
7455        int targetUid;
7456        if (needed != null) {
7457            targetUid = needed.targetUid;
7458        } else {
7459            try {
7460                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7461            } catch (RemoteException ex) {
7462                return null;
7463            }
7464            if (targetUid < 0) {
7465                if (DEBUG_URI_PERMISSION) {
7466                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7467                            + " on user " + targetUserId);
7468                }
7469                return null;
7470            }
7471        }
7472        if (data != null) {
7473            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7474            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7475                    targetUid);
7476            if (targetUid > 0) {
7477                if (needed == null) {
7478                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7479                }
7480                needed.add(grantUri);
7481            }
7482        }
7483        if (clip != null) {
7484            for (int i=0; i<clip.getItemCount(); i++) {
7485                Uri uri = clip.getItemAt(i).getUri();
7486                if (uri != null) {
7487                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7488                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7489                            targetUid);
7490                    if (targetUid > 0) {
7491                        if (needed == null) {
7492                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7493                        }
7494                        needed.add(grantUri);
7495                    }
7496                } else {
7497                    Intent clipIntent = clip.getItemAt(i).getIntent();
7498                    if (clipIntent != null) {
7499                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7500                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7501                        if (newNeeded != null) {
7502                            needed = newNeeded;
7503                        }
7504                    }
7505                }
7506            }
7507        }
7508
7509        return needed;
7510    }
7511
7512    /**
7513     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7514     */
7515    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7516            UriPermissionOwner owner) {
7517        if (needed != null) {
7518            for (int i=0; i<needed.size(); i++) {
7519                GrantUri grantUri = needed.get(i);
7520                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7521                        grantUri, needed.flags, owner);
7522            }
7523        }
7524    }
7525
7526    void grantUriPermissionFromIntentLocked(int callingUid,
7527            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7528        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7529                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7530        if (needed == null) {
7531            return;
7532        }
7533
7534        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7535    }
7536
7537    /**
7538     * @param uri This uri must NOT contain an embedded userId.
7539     * @param userId The userId in which the uri is to be resolved.
7540     */
7541    @Override
7542    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7543            final int modeFlags, int userId) {
7544        enforceNotIsolatedCaller("grantUriPermission");
7545        GrantUri grantUri = new GrantUri(userId, uri, false);
7546        synchronized(this) {
7547            final ProcessRecord r = getRecordForAppLocked(caller);
7548            if (r == null) {
7549                throw new SecurityException("Unable to find app for caller "
7550                        + caller
7551                        + " when granting permission to uri " + grantUri);
7552            }
7553            if (targetPkg == null) {
7554                throw new IllegalArgumentException("null target");
7555            }
7556            if (grantUri == null) {
7557                throw new IllegalArgumentException("null uri");
7558            }
7559
7560            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7561                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7562                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7563                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7564
7565            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7566                    UserHandle.getUserId(r.uid));
7567        }
7568    }
7569
7570    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7571        if (perm.modeFlags == 0) {
7572            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7573                    perm.targetUid);
7574            if (perms != null) {
7575                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7576                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7577
7578                perms.remove(perm.uri);
7579                if (perms.isEmpty()) {
7580                    mGrantedUriPermissions.remove(perm.targetUid);
7581                }
7582            }
7583        }
7584    }
7585
7586    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7587        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7588
7589        final IPackageManager pm = AppGlobals.getPackageManager();
7590        final String authority = grantUri.uri.getAuthority();
7591        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7592        if (pi == null) {
7593            Slog.w(TAG, "No content provider found for permission revoke: "
7594                    + grantUri.toSafeString());
7595            return;
7596        }
7597
7598        // Does the caller have this permission on the URI?
7599        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7600            // If they don't have direct access to the URI, then revoke any
7601            // ownerless URI permissions that have been granted to them.
7602            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7603            if (perms != null) {
7604                boolean persistChanged = false;
7605                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7606                    final UriPermission perm = it.next();
7607                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7608                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7609                        if (DEBUG_URI_PERMISSION)
7610                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7611                                    " permission to " + perm.uri);
7612                        persistChanged |= perm.revokeModes(
7613                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7614                        if (perm.modeFlags == 0) {
7615                            it.remove();
7616                        }
7617                    }
7618                }
7619                if (perms.isEmpty()) {
7620                    mGrantedUriPermissions.remove(callingUid);
7621                }
7622                if (persistChanged) {
7623                    schedulePersistUriGrants();
7624                }
7625            }
7626            return;
7627        }
7628
7629        boolean persistChanged = false;
7630
7631        // Go through all of the permissions and remove any that match.
7632        int N = mGrantedUriPermissions.size();
7633        for (int i = 0; i < N; i++) {
7634            final int targetUid = mGrantedUriPermissions.keyAt(i);
7635            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7636
7637            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7638                final UriPermission perm = it.next();
7639                if (perm.uri.sourceUserId == grantUri.sourceUserId
7640                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7641                    if (DEBUG_URI_PERMISSION)
7642                        Slog.v(TAG,
7643                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7644                    persistChanged |= perm.revokeModes(
7645                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7646                    if (perm.modeFlags == 0) {
7647                        it.remove();
7648                    }
7649                }
7650            }
7651
7652            if (perms.isEmpty()) {
7653                mGrantedUriPermissions.remove(targetUid);
7654                N--;
7655                i--;
7656            }
7657        }
7658
7659        if (persistChanged) {
7660            schedulePersistUriGrants();
7661        }
7662    }
7663
7664    /**
7665     * @param uri This uri must NOT contain an embedded userId.
7666     * @param userId The userId in which the uri is to be resolved.
7667     */
7668    @Override
7669    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7670            int userId) {
7671        enforceNotIsolatedCaller("revokeUriPermission");
7672        synchronized(this) {
7673            final ProcessRecord r = getRecordForAppLocked(caller);
7674            if (r == null) {
7675                throw new SecurityException("Unable to find app for caller "
7676                        + caller
7677                        + " when revoking permission to uri " + uri);
7678            }
7679            if (uri == null) {
7680                Slog.w(TAG, "revokeUriPermission: null uri");
7681                return;
7682            }
7683
7684            if (!Intent.isAccessUriMode(modeFlags)) {
7685                return;
7686            }
7687
7688            final IPackageManager pm = AppGlobals.getPackageManager();
7689            final String authority = uri.getAuthority();
7690            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7691            if (pi == null) {
7692                Slog.w(TAG, "No content provider found for permission revoke: "
7693                        + uri.toSafeString());
7694                return;
7695            }
7696
7697            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7698        }
7699    }
7700
7701    /**
7702     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7703     * given package.
7704     *
7705     * @param packageName Package name to match, or {@code null} to apply to all
7706     *            packages.
7707     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7708     *            to all users.
7709     * @param persistable If persistable grants should be removed.
7710     */
7711    private void removeUriPermissionsForPackageLocked(
7712            String packageName, int userHandle, boolean persistable) {
7713        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7714            throw new IllegalArgumentException("Must narrow by either package or user");
7715        }
7716
7717        boolean persistChanged = false;
7718
7719        int N = mGrantedUriPermissions.size();
7720        for (int i = 0; i < N; i++) {
7721            final int targetUid = mGrantedUriPermissions.keyAt(i);
7722            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7723
7724            // Only inspect grants matching user
7725            if (userHandle == UserHandle.USER_ALL
7726                    || userHandle == UserHandle.getUserId(targetUid)) {
7727                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7728                    final UriPermission perm = it.next();
7729
7730                    // Only inspect grants matching package
7731                    if (packageName == null || perm.sourcePkg.equals(packageName)
7732                            || perm.targetPkg.equals(packageName)) {
7733                        persistChanged |= perm.revokeModes(persistable
7734                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7735
7736                        // Only remove when no modes remain; any persisted grants
7737                        // will keep this alive.
7738                        if (perm.modeFlags == 0) {
7739                            it.remove();
7740                        }
7741                    }
7742                }
7743
7744                if (perms.isEmpty()) {
7745                    mGrantedUriPermissions.remove(targetUid);
7746                    N--;
7747                    i--;
7748                }
7749            }
7750        }
7751
7752        if (persistChanged) {
7753            schedulePersistUriGrants();
7754        }
7755    }
7756
7757    @Override
7758    public IBinder newUriPermissionOwner(String name) {
7759        enforceNotIsolatedCaller("newUriPermissionOwner");
7760        synchronized(this) {
7761            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7762            return owner.getExternalTokenLocked();
7763        }
7764    }
7765
7766    /**
7767     * @param uri This uri must NOT contain an embedded userId.
7768     * @param sourceUserId The userId in which the uri is to be resolved.
7769     * @param targetUserId The userId of the app that receives the grant.
7770     */
7771    @Override
7772    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7773            final int modeFlags, int sourceUserId, int targetUserId) {
7774        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7775                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7776        synchronized(this) {
7777            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7778            if (owner == null) {
7779                throw new IllegalArgumentException("Unknown owner: " + token);
7780            }
7781            if (fromUid != Binder.getCallingUid()) {
7782                if (Binder.getCallingUid() != Process.myUid()) {
7783                    // Only system code can grant URI permissions on behalf
7784                    // of other users.
7785                    throw new SecurityException("nice try");
7786                }
7787            }
7788            if (targetPkg == null) {
7789                throw new IllegalArgumentException("null target");
7790            }
7791            if (uri == null) {
7792                throw new IllegalArgumentException("null uri");
7793            }
7794
7795            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7796                    modeFlags, owner, targetUserId);
7797        }
7798    }
7799
7800    /**
7801     * @param uri This uri must NOT contain an embedded userId.
7802     * @param userId The userId in which the uri is to be resolved.
7803     */
7804    @Override
7805    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7806        synchronized(this) {
7807            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7808            if (owner == null) {
7809                throw new IllegalArgumentException("Unknown owner: " + token);
7810            }
7811
7812            if (uri == null) {
7813                owner.removeUriPermissionsLocked(mode);
7814            } else {
7815                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7816            }
7817        }
7818    }
7819
7820    private void schedulePersistUriGrants() {
7821        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7822            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7823                    10 * DateUtils.SECOND_IN_MILLIS);
7824        }
7825    }
7826
7827    private void writeGrantedUriPermissions() {
7828        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7829
7830        // Snapshot permissions so we can persist without lock
7831        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7832        synchronized (this) {
7833            final int size = mGrantedUriPermissions.size();
7834            for (int i = 0; i < size; i++) {
7835                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7836                for (UriPermission perm : perms.values()) {
7837                    if (perm.persistedModeFlags != 0) {
7838                        persist.add(perm.snapshot());
7839                    }
7840                }
7841            }
7842        }
7843
7844        FileOutputStream fos = null;
7845        try {
7846            fos = mGrantFile.startWrite();
7847
7848            XmlSerializer out = new FastXmlSerializer();
7849            out.setOutput(fos, "utf-8");
7850            out.startDocument(null, true);
7851            out.startTag(null, TAG_URI_GRANTS);
7852            for (UriPermission.Snapshot perm : persist) {
7853                out.startTag(null, TAG_URI_GRANT);
7854                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7855                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7856                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7857                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7858                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7859                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7860                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7861                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7862                out.endTag(null, TAG_URI_GRANT);
7863            }
7864            out.endTag(null, TAG_URI_GRANTS);
7865            out.endDocument();
7866
7867            mGrantFile.finishWrite(fos);
7868        } catch (IOException e) {
7869            if (fos != null) {
7870                mGrantFile.failWrite(fos);
7871            }
7872        }
7873    }
7874
7875    private void readGrantedUriPermissionsLocked() {
7876        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7877
7878        final long now = System.currentTimeMillis();
7879
7880        FileInputStream fis = null;
7881        try {
7882            fis = mGrantFile.openRead();
7883            final XmlPullParser in = Xml.newPullParser();
7884            in.setInput(fis, null);
7885
7886            int type;
7887            while ((type = in.next()) != END_DOCUMENT) {
7888                final String tag = in.getName();
7889                if (type == START_TAG) {
7890                    if (TAG_URI_GRANT.equals(tag)) {
7891                        final int sourceUserId;
7892                        final int targetUserId;
7893                        final int userHandle = readIntAttribute(in,
7894                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7895                        if (userHandle != UserHandle.USER_NULL) {
7896                            // For backwards compatibility.
7897                            sourceUserId = userHandle;
7898                            targetUserId = userHandle;
7899                        } else {
7900                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7901                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7902                        }
7903                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7904                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7905                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7906                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7907                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7908                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7909
7910                        // Sanity check that provider still belongs to source package
7911                        final ProviderInfo pi = getProviderInfoLocked(
7912                                uri.getAuthority(), sourceUserId);
7913                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7914                            int targetUid = -1;
7915                            try {
7916                                targetUid = AppGlobals.getPackageManager()
7917                                        .getPackageUid(targetPkg, targetUserId);
7918                            } catch (RemoteException e) {
7919                            }
7920                            if (targetUid != -1) {
7921                                final UriPermission perm = findOrCreateUriPermissionLocked(
7922                                        sourcePkg, targetPkg, targetUid,
7923                                        new GrantUri(sourceUserId, uri, prefix));
7924                                perm.initPersistedModes(modeFlags, createdTime);
7925                            }
7926                        } else {
7927                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7928                                    + " but instead found " + pi);
7929                        }
7930                    }
7931                }
7932            }
7933        } catch (FileNotFoundException e) {
7934            // Missing grants is okay
7935        } catch (IOException e) {
7936            Slog.wtf(TAG, "Failed reading Uri grants", e);
7937        } catch (XmlPullParserException e) {
7938            Slog.wtf(TAG, "Failed reading Uri grants", e);
7939        } finally {
7940            IoUtils.closeQuietly(fis);
7941        }
7942    }
7943
7944    /**
7945     * @param uri This uri must NOT contain an embedded userId.
7946     * @param userId The userId in which the uri is to be resolved.
7947     */
7948    @Override
7949    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7950        enforceNotIsolatedCaller("takePersistableUriPermission");
7951
7952        Preconditions.checkFlagsArgument(modeFlags,
7953                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7954
7955        synchronized (this) {
7956            final int callingUid = Binder.getCallingUid();
7957            boolean persistChanged = false;
7958            GrantUri grantUri = new GrantUri(userId, uri, false);
7959
7960            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7961                    new GrantUri(userId, uri, false));
7962            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7963                    new GrantUri(userId, uri, true));
7964
7965            final boolean exactValid = (exactPerm != null)
7966                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7967            final boolean prefixValid = (prefixPerm != null)
7968                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7969
7970            if (!(exactValid || prefixValid)) {
7971                throw new SecurityException("No persistable permission grants found for UID "
7972                        + callingUid + " and Uri " + grantUri.toSafeString());
7973            }
7974
7975            if (exactValid) {
7976                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7977            }
7978            if (prefixValid) {
7979                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7980            }
7981
7982            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7983
7984            if (persistChanged) {
7985                schedulePersistUriGrants();
7986            }
7987        }
7988    }
7989
7990    /**
7991     * @param uri This uri must NOT contain an embedded userId.
7992     * @param userId The userId in which the uri is to be resolved.
7993     */
7994    @Override
7995    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7996        enforceNotIsolatedCaller("releasePersistableUriPermission");
7997
7998        Preconditions.checkFlagsArgument(modeFlags,
7999                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8000
8001        synchronized (this) {
8002            final int callingUid = Binder.getCallingUid();
8003            boolean persistChanged = false;
8004
8005            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8006                    new GrantUri(userId, uri, false));
8007            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8008                    new GrantUri(userId, uri, true));
8009            if (exactPerm == null && prefixPerm == null) {
8010                throw new SecurityException("No permission grants found for UID " + callingUid
8011                        + " and Uri " + uri.toSafeString());
8012            }
8013
8014            if (exactPerm != null) {
8015                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8016                removeUriPermissionIfNeededLocked(exactPerm);
8017            }
8018            if (prefixPerm != null) {
8019                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8020                removeUriPermissionIfNeededLocked(prefixPerm);
8021            }
8022
8023            if (persistChanged) {
8024                schedulePersistUriGrants();
8025            }
8026        }
8027    }
8028
8029    /**
8030     * Prune any older {@link UriPermission} for the given UID until outstanding
8031     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8032     *
8033     * @return if any mutations occured that require persisting.
8034     */
8035    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8036        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8037        if (perms == null) return false;
8038        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8039
8040        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8041        for (UriPermission perm : perms.values()) {
8042            if (perm.persistedModeFlags != 0) {
8043                persisted.add(perm);
8044            }
8045        }
8046
8047        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8048        if (trimCount <= 0) return false;
8049
8050        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8051        for (int i = 0; i < trimCount; i++) {
8052            final UriPermission perm = persisted.get(i);
8053
8054            if (DEBUG_URI_PERMISSION) {
8055                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8056            }
8057
8058            perm.releasePersistableModes(~0);
8059            removeUriPermissionIfNeededLocked(perm);
8060        }
8061
8062        return true;
8063    }
8064
8065    @Override
8066    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8067            String packageName, boolean incoming) {
8068        enforceNotIsolatedCaller("getPersistedUriPermissions");
8069        Preconditions.checkNotNull(packageName, "packageName");
8070
8071        final int callingUid = Binder.getCallingUid();
8072        final IPackageManager pm = AppGlobals.getPackageManager();
8073        try {
8074            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8075            if (packageUid != callingUid) {
8076                throw new SecurityException(
8077                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8078            }
8079        } catch (RemoteException e) {
8080            throw new SecurityException("Failed to verify package name ownership");
8081        }
8082
8083        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8084        synchronized (this) {
8085            if (incoming) {
8086                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8087                        callingUid);
8088                if (perms == null) {
8089                    Slog.w(TAG, "No permission grants found for " + packageName);
8090                } else {
8091                    for (UriPermission perm : perms.values()) {
8092                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8093                            result.add(perm.buildPersistedPublicApiObject());
8094                        }
8095                    }
8096                }
8097            } else {
8098                final int size = mGrantedUriPermissions.size();
8099                for (int i = 0; i < size; i++) {
8100                    final ArrayMap<GrantUri, UriPermission> perms =
8101                            mGrantedUriPermissions.valueAt(i);
8102                    for (UriPermission perm : perms.values()) {
8103                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8104                            result.add(perm.buildPersistedPublicApiObject());
8105                        }
8106                    }
8107                }
8108            }
8109        }
8110        return new ParceledListSlice<android.content.UriPermission>(result);
8111    }
8112
8113    @Override
8114    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8115        synchronized (this) {
8116            ProcessRecord app =
8117                who != null ? getRecordForAppLocked(who) : null;
8118            if (app == null) return;
8119
8120            Message msg = Message.obtain();
8121            msg.what = WAIT_FOR_DEBUGGER_MSG;
8122            msg.obj = app;
8123            msg.arg1 = waiting ? 1 : 0;
8124            mHandler.sendMessage(msg);
8125        }
8126    }
8127
8128    @Override
8129    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8130        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8131        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8132        outInfo.availMem = Process.getFreeMemory();
8133        outInfo.totalMem = Process.getTotalMemory();
8134        outInfo.threshold = homeAppMem;
8135        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8136        outInfo.hiddenAppThreshold = cachedAppMem;
8137        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8138                ProcessList.SERVICE_ADJ);
8139        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8140                ProcessList.VISIBLE_APP_ADJ);
8141        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8142                ProcessList.FOREGROUND_APP_ADJ);
8143    }
8144
8145    // =========================================================
8146    // TASK MANAGEMENT
8147    // =========================================================
8148
8149    @Override
8150    public List<IAppTask> getAppTasks(String callingPackage) {
8151        int callingUid = Binder.getCallingUid();
8152        long ident = Binder.clearCallingIdentity();
8153
8154        synchronized(this) {
8155            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8156            try {
8157                if (localLOGV) Slog.v(TAG, "getAppTasks");
8158
8159                final int N = mRecentTasks.size();
8160                for (int i = 0; i < N; i++) {
8161                    TaskRecord tr = mRecentTasks.get(i);
8162                    // Skip tasks that do not match the caller.  We don't need to verify
8163                    // callingPackage, because we are also limiting to callingUid and know
8164                    // that will limit to the correct security sandbox.
8165                    if (tr.effectiveUid != callingUid) {
8166                        continue;
8167                    }
8168                    Intent intent = tr.getBaseIntent();
8169                    if (intent == null ||
8170                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8171                        continue;
8172                    }
8173                    ActivityManager.RecentTaskInfo taskInfo =
8174                            createRecentTaskInfoFromTaskRecord(tr);
8175                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8176                    list.add(taskImpl);
8177                }
8178            } finally {
8179                Binder.restoreCallingIdentity(ident);
8180            }
8181            return list;
8182        }
8183    }
8184
8185    @Override
8186    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8187        final int callingUid = Binder.getCallingUid();
8188        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8189
8190        synchronized(this) {
8191            if (localLOGV) Slog.v(
8192                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8193
8194            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8195                    callingUid);
8196
8197            // TODO: Improve with MRU list from all ActivityStacks.
8198            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8199        }
8200
8201        return list;
8202    }
8203
8204    TaskRecord getMostRecentTask() {
8205        return mRecentTasks.get(0);
8206    }
8207
8208    /**
8209     * Creates a new RecentTaskInfo from a TaskRecord.
8210     */
8211    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8212        // Update the task description to reflect any changes in the task stack
8213        tr.updateTaskDescription();
8214
8215        // Compose the recent task info
8216        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8217        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8218        rti.persistentId = tr.taskId;
8219        rti.baseIntent = new Intent(tr.getBaseIntent());
8220        rti.origActivity = tr.origActivity;
8221        rti.description = tr.lastDescription;
8222        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8223        rti.userId = tr.userId;
8224        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8225        rti.firstActiveTime = tr.firstActiveTime;
8226        rti.lastActiveTime = tr.lastActiveTime;
8227        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8228        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8229        return rti;
8230    }
8231
8232    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8233        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8234                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8235        if (!allowed) {
8236            if (checkPermission(android.Manifest.permission.GET_TASKS,
8237                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8238                // Temporary compatibility: some existing apps on the system image may
8239                // still be requesting the old permission and not switched to the new
8240                // one; if so, we'll still allow them full access.  This means we need
8241                // to see if they are holding the old permission and are a system app.
8242                try {
8243                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8244                        allowed = true;
8245                        Slog.w(TAG, caller + ": caller " + callingUid
8246                                + " is using old GET_TASKS but privileged; allowing");
8247                    }
8248                } catch (RemoteException e) {
8249                }
8250            }
8251        }
8252        if (!allowed) {
8253            Slog.w(TAG, caller + ": caller " + callingUid
8254                    + " does not hold GET_TASKS; limiting output");
8255        }
8256        return allowed;
8257    }
8258
8259    @Override
8260    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8261        final int callingUid = Binder.getCallingUid();
8262        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8263                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8264
8265        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8266        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8267        synchronized (this) {
8268            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8269                    callingUid);
8270            final boolean detailed = checkCallingPermission(
8271                    android.Manifest.permission.GET_DETAILED_TASKS)
8272                    == PackageManager.PERMISSION_GRANTED;
8273
8274            final int N = mRecentTasks.size();
8275            ArrayList<ActivityManager.RecentTaskInfo> res
8276                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8277                            maxNum < N ? maxNum : N);
8278
8279            final Set<Integer> includedUsers;
8280            if (includeProfiles) {
8281                includedUsers = getProfileIdsLocked(userId);
8282            } else {
8283                includedUsers = new HashSet<Integer>();
8284            }
8285            includedUsers.add(Integer.valueOf(userId));
8286
8287            for (int i=0; i<N && maxNum > 0; i++) {
8288                TaskRecord tr = mRecentTasks.get(i);
8289                // Only add calling user or related users recent tasks
8290                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8291                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8292                    continue;
8293                }
8294
8295                // Return the entry if desired by the caller.  We always return
8296                // the first entry, because callers always expect this to be the
8297                // foreground app.  We may filter others if the caller has
8298                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8299                // we should exclude the entry.
8300
8301                if (i == 0
8302                        || withExcluded
8303                        || (tr.intent == null)
8304                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8305                                == 0)) {
8306                    if (!allowed) {
8307                        // If the caller doesn't have the GET_TASKS permission, then only
8308                        // allow them to see a small subset of tasks -- their own and home.
8309                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8310                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8311                            continue;
8312                        }
8313                    }
8314                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8315                        if (tr.stack != null && tr.stack.isHomeStack()) {
8316                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8317                            continue;
8318                        }
8319                    }
8320                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8321                        // Don't include auto remove tasks that are finished or finishing.
8322                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8323                                + tr);
8324                        continue;
8325                    }
8326                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8327                            && !tr.isAvailable) {
8328                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8329                        continue;
8330                    }
8331
8332                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8333                    if (!detailed) {
8334                        rti.baseIntent.replaceExtras((Bundle)null);
8335                    }
8336
8337                    res.add(rti);
8338                    maxNum--;
8339                }
8340            }
8341            return res;
8342        }
8343    }
8344
8345    private TaskRecord recentTaskForIdLocked(int id) {
8346        final int N = mRecentTasks.size();
8347            for (int i=0; i<N; i++) {
8348                TaskRecord tr = mRecentTasks.get(i);
8349                if (tr.taskId == id) {
8350                    return tr;
8351                }
8352            }
8353            return null;
8354    }
8355
8356    @Override
8357    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8358        synchronized (this) {
8359            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8360                    "getTaskThumbnail()");
8361            TaskRecord tr = recentTaskForIdLocked(id);
8362            if (tr != null) {
8363                return tr.getTaskThumbnailLocked();
8364            }
8365        }
8366        return null;
8367    }
8368
8369    @Override
8370    public int addAppTask(IBinder activityToken, Intent intent,
8371            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8372        final int callingUid = Binder.getCallingUid();
8373        final long callingIdent = Binder.clearCallingIdentity();
8374
8375        try {
8376            synchronized (this) {
8377                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8378                if (r == null) {
8379                    throw new IllegalArgumentException("Activity does not exist; token="
8380                            + activityToken);
8381                }
8382                ComponentName comp = intent.getComponent();
8383                if (comp == null) {
8384                    throw new IllegalArgumentException("Intent " + intent
8385                            + " must specify explicit component");
8386                }
8387                if (thumbnail.getWidth() != mThumbnailWidth
8388                        || thumbnail.getHeight() != mThumbnailHeight) {
8389                    throw new IllegalArgumentException("Bad thumbnail size: got "
8390                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8391                            + mThumbnailWidth + "x" + mThumbnailHeight);
8392                }
8393                if (intent.getSelector() != null) {
8394                    intent.setSelector(null);
8395                }
8396                if (intent.getSourceBounds() != null) {
8397                    intent.setSourceBounds(null);
8398                }
8399                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8400                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8401                        // The caller has added this as an auto-remove task...  that makes no
8402                        // sense, so turn off auto-remove.
8403                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8404                    }
8405                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8406                    // Must be a new task.
8407                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8408                }
8409                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8410                    mLastAddedTaskActivity = null;
8411                }
8412                ActivityInfo ainfo = mLastAddedTaskActivity;
8413                if (ainfo == null) {
8414                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8415                            comp, 0, UserHandle.getUserId(callingUid));
8416                    if (ainfo.applicationInfo.uid != callingUid) {
8417                        throw new SecurityException(
8418                                "Can't add task for another application: target uid="
8419                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8420                    }
8421                }
8422
8423                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8424                        intent, description);
8425
8426                int trimIdx = trimRecentsForTask(task, false);
8427                if (trimIdx >= 0) {
8428                    // If this would have caused a trim, then we'll abort because that
8429                    // means it would be added at the end of the list but then just removed.
8430                    return -1;
8431                }
8432
8433                final int N = mRecentTasks.size();
8434                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8435                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8436                    tr.removedFromRecents(mTaskPersister);
8437                }
8438
8439                task.inRecents = true;
8440                mRecentTasks.add(task);
8441                r.task.stack.addTask(task, false, false);
8442
8443                task.setLastThumbnail(thumbnail);
8444                task.freeLastThumbnail();
8445
8446                return task.taskId;
8447            }
8448        } finally {
8449            Binder.restoreCallingIdentity(callingIdent);
8450        }
8451    }
8452
8453    @Override
8454    public Point getAppTaskThumbnailSize() {
8455        synchronized (this) {
8456            return new Point(mThumbnailWidth,  mThumbnailHeight);
8457        }
8458    }
8459
8460    @Override
8461    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8462        synchronized (this) {
8463            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8464            if (r != null) {
8465                r.setTaskDescription(td);
8466                r.task.updateTaskDescription();
8467            }
8468        }
8469    }
8470
8471    @Override
8472    public Bitmap getTaskDescriptionIcon(String filename) {
8473        if (!FileUtils.isValidExtFilename(filename)
8474                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8475            throw new IllegalArgumentException("Bad filename: " + filename);
8476        }
8477        return mTaskPersister.getTaskDescriptionIcon(filename);
8478    }
8479
8480    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8481        mRecentTasks.remove(tr);
8482        tr.removedFromRecents(mTaskPersister);
8483        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8484        Intent baseIntent = new Intent(
8485                tr.intent != null ? tr.intent : tr.affinityIntent);
8486        ComponentName component = baseIntent.getComponent();
8487        if (component == null) {
8488            Slog.w(TAG, "Now component for base intent of task: " + tr);
8489            return;
8490        }
8491
8492        // Find any running services associated with this app.
8493        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8494
8495        if (killProcesses) {
8496            // Find any running processes associated with this app.
8497            final String pkg = component.getPackageName();
8498            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8499            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8500            for (int i=0; i<pmap.size(); i++) {
8501                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8502                for (int j=0; j<uids.size(); j++) {
8503                    ProcessRecord proc = uids.valueAt(j);
8504                    if (proc.userId != tr.userId) {
8505                        continue;
8506                    }
8507                    if (!proc.pkgList.containsKey(pkg)) {
8508                        continue;
8509                    }
8510                    procs.add(proc);
8511                }
8512            }
8513
8514            // Kill the running processes.
8515            for (int i=0; i<procs.size(); i++) {
8516                ProcessRecord pr = procs.get(i);
8517                if (pr == mHomeProcess) {
8518                    // Don't kill the home process along with tasks from the same package.
8519                    continue;
8520                }
8521                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8522                    pr.kill("remove task", true);
8523                } else {
8524                    pr.waitingToKill = "remove task";
8525                }
8526            }
8527        }
8528    }
8529
8530    /**
8531     * Removes the task with the specified task id.
8532     *
8533     * @param taskId Identifier of the task to be removed.
8534     * @param flags Additional operational flags.  May be 0 or
8535     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8536     * @return Returns true if the given task was found and removed.
8537     */
8538    private boolean removeTaskByIdLocked(int taskId, int flags) {
8539        TaskRecord tr = recentTaskForIdLocked(taskId);
8540        if (tr != null) {
8541            tr.removeTaskActivitiesLocked();
8542            cleanUpRemovedTaskLocked(tr, flags);
8543            if (tr.isPersistable) {
8544                notifyTaskPersisterLocked(null, true);
8545            }
8546            return true;
8547        }
8548        return false;
8549    }
8550
8551    @Override
8552    public boolean removeTask(int taskId, int flags) {
8553        synchronized (this) {
8554            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8555                    "removeTask()");
8556            long ident = Binder.clearCallingIdentity();
8557            try {
8558                return removeTaskByIdLocked(taskId, flags);
8559            } finally {
8560                Binder.restoreCallingIdentity(ident);
8561            }
8562        }
8563    }
8564
8565    /**
8566     * TODO: Add mController hook
8567     */
8568    @Override
8569    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8570        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8571                "moveTaskToFront()");
8572
8573        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8574        synchronized(this) {
8575            moveTaskToFrontLocked(taskId, flags, options);
8576        }
8577    }
8578
8579    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8580        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8581                Binder.getCallingUid(), -1, -1, "Task to front")) {
8582            ActivityOptions.abort(options);
8583            return;
8584        }
8585        final long origId = Binder.clearCallingIdentity();
8586        try {
8587            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8588            if (task == null) {
8589                return;
8590            }
8591            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8592                mStackSupervisor.showLockTaskToast();
8593                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8594                return;
8595            }
8596            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8597            if (prev != null && prev.isRecentsActivity()) {
8598                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8599            }
8600            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8601        } finally {
8602            Binder.restoreCallingIdentity(origId);
8603        }
8604        ActivityOptions.abort(options);
8605    }
8606
8607    @Override
8608    public void moveTaskToBack(int taskId) {
8609        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8610                "moveTaskToBack()");
8611
8612        synchronized(this) {
8613            TaskRecord tr = recentTaskForIdLocked(taskId);
8614            if (tr != null) {
8615                if (tr == mStackSupervisor.mLockTaskModeTask) {
8616                    mStackSupervisor.showLockTaskToast();
8617                    return;
8618                }
8619                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8620                ActivityStack stack = tr.stack;
8621                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8622                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8623                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8624                        return;
8625                    }
8626                }
8627                final long origId = Binder.clearCallingIdentity();
8628                try {
8629                    stack.moveTaskToBackLocked(taskId, null);
8630                } finally {
8631                    Binder.restoreCallingIdentity(origId);
8632                }
8633            }
8634        }
8635    }
8636
8637    /**
8638     * Moves an activity, and all of the other activities within the same task, to the bottom
8639     * of the history stack.  The activity's order within the task is unchanged.
8640     *
8641     * @param token A reference to the activity we wish to move
8642     * @param nonRoot If false then this only works if the activity is the root
8643     *                of a task; if true it will work for any activity in a task.
8644     * @return Returns true if the move completed, false if not.
8645     */
8646    @Override
8647    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8648        enforceNotIsolatedCaller("moveActivityTaskToBack");
8649        synchronized(this) {
8650            final long origId = Binder.clearCallingIdentity();
8651            try {
8652                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8653                if (taskId >= 0) {
8654                    if ((mStackSupervisor.mLockTaskModeTask != null)
8655                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8656                        mStackSupervisor.showLockTaskToast();
8657                        return false;
8658                    }
8659                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8660                }
8661            } finally {
8662                Binder.restoreCallingIdentity(origId);
8663            }
8664        }
8665        return false;
8666    }
8667
8668    @Override
8669    public void moveTaskBackwards(int task) {
8670        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8671                "moveTaskBackwards()");
8672
8673        synchronized(this) {
8674            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8675                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8676                return;
8677            }
8678            final long origId = Binder.clearCallingIdentity();
8679            moveTaskBackwardsLocked(task);
8680            Binder.restoreCallingIdentity(origId);
8681        }
8682    }
8683
8684    private final void moveTaskBackwardsLocked(int task) {
8685        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8686    }
8687
8688    @Override
8689    public IBinder getHomeActivityToken() throws RemoteException {
8690        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8691                "getHomeActivityToken()");
8692        synchronized (this) {
8693            return mStackSupervisor.getHomeActivityToken();
8694        }
8695    }
8696
8697    @Override
8698    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8699            IActivityContainerCallback callback) throws RemoteException {
8700        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8701                "createActivityContainer()");
8702        synchronized (this) {
8703            if (parentActivityToken == null) {
8704                throw new IllegalArgumentException("parent token must not be null");
8705            }
8706            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8707            if (r == null) {
8708                return null;
8709            }
8710            if (callback == null) {
8711                throw new IllegalArgumentException("callback must not be null");
8712            }
8713            return mStackSupervisor.createActivityContainer(r, callback);
8714        }
8715    }
8716
8717    @Override
8718    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8719        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8720                "deleteActivityContainer()");
8721        synchronized (this) {
8722            mStackSupervisor.deleteActivityContainer(container);
8723        }
8724    }
8725
8726    @Override
8727    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8728            throws RemoteException {
8729        synchronized (this) {
8730            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8731            if (stack != null) {
8732                return stack.mActivityContainer;
8733            }
8734            return null;
8735        }
8736    }
8737
8738    @Override
8739    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8740        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8741                "moveTaskToStack()");
8742        if (stackId == HOME_STACK_ID) {
8743            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8744                    new RuntimeException("here").fillInStackTrace());
8745        }
8746        synchronized (this) {
8747            long ident = Binder.clearCallingIdentity();
8748            try {
8749                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8750                        + stackId + " toTop=" + toTop);
8751                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8752            } finally {
8753                Binder.restoreCallingIdentity(ident);
8754            }
8755        }
8756    }
8757
8758    @Override
8759    public void resizeStack(int stackBoxId, Rect bounds) {
8760        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8761                "resizeStackBox()");
8762        long ident = Binder.clearCallingIdentity();
8763        try {
8764            mWindowManager.resizeStack(stackBoxId, bounds);
8765        } finally {
8766            Binder.restoreCallingIdentity(ident);
8767        }
8768    }
8769
8770    @Override
8771    public List<StackInfo> getAllStackInfos() {
8772        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8773                "getAllStackInfos()");
8774        long ident = Binder.clearCallingIdentity();
8775        try {
8776            synchronized (this) {
8777                return mStackSupervisor.getAllStackInfosLocked();
8778            }
8779        } finally {
8780            Binder.restoreCallingIdentity(ident);
8781        }
8782    }
8783
8784    @Override
8785    public StackInfo getStackInfo(int stackId) {
8786        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8787                "getStackInfo()");
8788        long ident = Binder.clearCallingIdentity();
8789        try {
8790            synchronized (this) {
8791                return mStackSupervisor.getStackInfoLocked(stackId);
8792            }
8793        } finally {
8794            Binder.restoreCallingIdentity(ident);
8795        }
8796    }
8797
8798    @Override
8799    public boolean isInHomeStack(int taskId) {
8800        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8801                "getStackInfo()");
8802        long ident = Binder.clearCallingIdentity();
8803        try {
8804            synchronized (this) {
8805                TaskRecord tr = recentTaskForIdLocked(taskId);
8806                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8807            }
8808        } finally {
8809            Binder.restoreCallingIdentity(ident);
8810        }
8811    }
8812
8813    @Override
8814    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8815        synchronized(this) {
8816            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8817        }
8818    }
8819
8820    private boolean isLockTaskAuthorized(String pkg) {
8821        final DevicePolicyManager dpm = (DevicePolicyManager)
8822                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8823        try {
8824            int uid = mContext.getPackageManager().getPackageUid(pkg,
8825                    Binder.getCallingUserHandle().getIdentifier());
8826            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8827        } catch (NameNotFoundException e) {
8828            return false;
8829        }
8830    }
8831
8832    void startLockTaskMode(TaskRecord task) {
8833        final String pkg;
8834        synchronized (this) {
8835            pkg = task.intent.getComponent().getPackageName();
8836        }
8837        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8838        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8839            final TaskRecord taskRecord = task;
8840            mHandler.post(new Runnable() {
8841                @Override
8842                public void run() {
8843                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8844                }
8845            });
8846            return;
8847        }
8848        long ident = Binder.clearCallingIdentity();
8849        try {
8850            synchronized (this) {
8851                // Since we lost lock on task, make sure it is still there.
8852                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8853                if (task != null) {
8854                    if (!isSystemInitiated
8855                            && ((mStackSupervisor.getFocusedStack() == null)
8856                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8857                        throw new IllegalArgumentException("Invalid task, not in foreground");
8858                    }
8859                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8860                }
8861            }
8862        } finally {
8863            Binder.restoreCallingIdentity(ident);
8864        }
8865    }
8866
8867    @Override
8868    public void startLockTaskMode(int taskId) {
8869        final TaskRecord task;
8870        long ident = Binder.clearCallingIdentity();
8871        try {
8872            synchronized (this) {
8873                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8874            }
8875        } finally {
8876            Binder.restoreCallingIdentity(ident);
8877        }
8878        if (task != null) {
8879            startLockTaskMode(task);
8880        }
8881    }
8882
8883    @Override
8884    public void startLockTaskMode(IBinder token) {
8885        final TaskRecord task;
8886        long ident = Binder.clearCallingIdentity();
8887        try {
8888            synchronized (this) {
8889                final ActivityRecord r = ActivityRecord.forToken(token);
8890                if (r == null) {
8891                    return;
8892                }
8893                task = r.task;
8894            }
8895        } finally {
8896            Binder.restoreCallingIdentity(ident);
8897        }
8898        if (task != null) {
8899            startLockTaskMode(task);
8900        }
8901    }
8902
8903    @Override
8904    public void startLockTaskModeOnCurrent() throws RemoteException {
8905        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8906                "startLockTaskModeOnCurrent");
8907        ActivityRecord r = null;
8908        synchronized (this) {
8909            r = mStackSupervisor.topRunningActivityLocked();
8910        }
8911        startLockTaskMode(r.task);
8912    }
8913
8914    @Override
8915    public void stopLockTaskMode() {
8916        // Verify that the user matches the package of the intent for the TaskRecord
8917        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8918        // and stopLockTaskMode.
8919        final int callingUid = Binder.getCallingUid();
8920        if (callingUid != Process.SYSTEM_UID) {
8921            try {
8922                String pkg =
8923                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8924                int uid = mContext.getPackageManager().getPackageUid(pkg,
8925                        Binder.getCallingUserHandle().getIdentifier());
8926                if (uid != callingUid) {
8927                    throw new SecurityException("Invalid uid, expected " + uid);
8928                }
8929            } catch (NameNotFoundException e) {
8930                Log.d(TAG, "stopLockTaskMode " + e);
8931                return;
8932            }
8933        }
8934        long ident = Binder.clearCallingIdentity();
8935        try {
8936            Log.d(TAG, "stopLockTaskMode");
8937            // Stop lock task
8938            synchronized (this) {
8939                mStackSupervisor.setLockTaskModeLocked(null, false);
8940            }
8941        } finally {
8942            Binder.restoreCallingIdentity(ident);
8943        }
8944    }
8945
8946    @Override
8947    public void stopLockTaskModeOnCurrent() throws RemoteException {
8948        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8949                "stopLockTaskModeOnCurrent");
8950        long ident = Binder.clearCallingIdentity();
8951        try {
8952            stopLockTaskMode();
8953        } finally {
8954            Binder.restoreCallingIdentity(ident);
8955        }
8956    }
8957
8958    @Override
8959    public boolean isInLockTaskMode() {
8960        synchronized (this) {
8961            return mStackSupervisor.isInLockTaskMode();
8962        }
8963    }
8964
8965    // =========================================================
8966    // CONTENT PROVIDERS
8967    // =========================================================
8968
8969    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8970        List<ProviderInfo> providers = null;
8971        try {
8972            providers = AppGlobals.getPackageManager().
8973                queryContentProviders(app.processName, app.uid,
8974                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8975        } catch (RemoteException ex) {
8976        }
8977        if (DEBUG_MU)
8978            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8979        int userId = app.userId;
8980        if (providers != null) {
8981            int N = providers.size();
8982            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8983            for (int i=0; i<N; i++) {
8984                ProviderInfo cpi =
8985                    (ProviderInfo)providers.get(i);
8986                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8987                        cpi.name, cpi.flags);
8988                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8989                    // This is a singleton provider, but a user besides the
8990                    // default user is asking to initialize a process it runs
8991                    // in...  well, no, it doesn't actually run in this process,
8992                    // it runs in the process of the default user.  Get rid of it.
8993                    providers.remove(i);
8994                    N--;
8995                    i--;
8996                    continue;
8997                }
8998
8999                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9000                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9001                if (cpr == null) {
9002                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9003                    mProviderMap.putProviderByClass(comp, cpr);
9004                }
9005                if (DEBUG_MU)
9006                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9007                app.pubProviders.put(cpi.name, cpr);
9008                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9009                    // Don't add this if it is a platform component that is marked
9010                    // to run in multiple processes, because this is actually
9011                    // part of the framework so doesn't make sense to track as a
9012                    // separate apk in the process.
9013                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9014                            mProcessStats);
9015                }
9016                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9017            }
9018        }
9019        return providers;
9020    }
9021
9022    /**
9023     * Check if {@link ProcessRecord} has a possible chance at accessing the
9024     * given {@link ProviderInfo}. Final permission checking is always done
9025     * in {@link ContentProvider}.
9026     */
9027    private final String checkContentProviderPermissionLocked(
9028            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9029        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9030        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9031        boolean checkedGrants = false;
9032        if (checkUser) {
9033            // Looking for cross-user grants before enforcing the typical cross-users permissions
9034            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9035            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9036                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9037                    return null;
9038                }
9039                checkedGrants = true;
9040            }
9041            userId = handleIncomingUser(callingPid, callingUid, userId,
9042                    false, ALLOW_NON_FULL,
9043                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9044            if (userId != tmpTargetUserId) {
9045                // When we actually went to determine the final targer user ID, this ended
9046                // up different than our initial check for the authority.  This is because
9047                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9048                // SELF.  So we need to re-check the grants again.
9049                checkedGrants = false;
9050            }
9051        }
9052        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9053                cpi.applicationInfo.uid, cpi.exported)
9054                == PackageManager.PERMISSION_GRANTED) {
9055            return null;
9056        }
9057        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9058                cpi.applicationInfo.uid, cpi.exported)
9059                == PackageManager.PERMISSION_GRANTED) {
9060            return null;
9061        }
9062
9063        PathPermission[] pps = cpi.pathPermissions;
9064        if (pps != null) {
9065            int i = pps.length;
9066            while (i > 0) {
9067                i--;
9068                PathPermission pp = pps[i];
9069                String pprperm = pp.getReadPermission();
9070                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9071                        cpi.applicationInfo.uid, cpi.exported)
9072                        == PackageManager.PERMISSION_GRANTED) {
9073                    return null;
9074                }
9075                String ppwperm = pp.getWritePermission();
9076                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9077                        cpi.applicationInfo.uid, cpi.exported)
9078                        == PackageManager.PERMISSION_GRANTED) {
9079                    return null;
9080                }
9081            }
9082        }
9083        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9084            return null;
9085        }
9086
9087        String msg;
9088        if (!cpi.exported) {
9089            msg = "Permission Denial: opening provider " + cpi.name
9090                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9091                    + ", uid=" + callingUid + ") that is not exported from uid "
9092                    + cpi.applicationInfo.uid;
9093        } else {
9094            msg = "Permission Denial: opening provider " + cpi.name
9095                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9096                    + ", uid=" + callingUid + ") requires "
9097                    + cpi.readPermission + " or " + cpi.writePermission;
9098        }
9099        Slog.w(TAG, msg);
9100        return msg;
9101    }
9102
9103    /**
9104     * Returns if the ContentProvider has granted a uri to callingUid
9105     */
9106    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9107        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9108        if (perms != null) {
9109            for (int i=perms.size()-1; i>=0; i--) {
9110                GrantUri grantUri = perms.keyAt(i);
9111                if (grantUri.sourceUserId == userId || !checkUser) {
9112                    if (matchesProvider(grantUri.uri, cpi)) {
9113                        return true;
9114                    }
9115                }
9116            }
9117        }
9118        return false;
9119    }
9120
9121    /**
9122     * Returns true if the uri authority is one of the authorities specified in the provider.
9123     */
9124    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9125        String uriAuth = uri.getAuthority();
9126        String cpiAuth = cpi.authority;
9127        if (cpiAuth.indexOf(';') == -1) {
9128            return cpiAuth.equals(uriAuth);
9129        }
9130        String[] cpiAuths = cpiAuth.split(";");
9131        int length = cpiAuths.length;
9132        for (int i = 0; i < length; i++) {
9133            if (cpiAuths[i].equals(uriAuth)) return true;
9134        }
9135        return false;
9136    }
9137
9138    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9139            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9140        if (r != null) {
9141            for (int i=0; i<r.conProviders.size(); i++) {
9142                ContentProviderConnection conn = r.conProviders.get(i);
9143                if (conn.provider == cpr) {
9144                    if (DEBUG_PROVIDER) Slog.v(TAG,
9145                            "Adding provider requested by "
9146                            + r.processName + " from process "
9147                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9148                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9149                    if (stable) {
9150                        conn.stableCount++;
9151                        conn.numStableIncs++;
9152                    } else {
9153                        conn.unstableCount++;
9154                        conn.numUnstableIncs++;
9155                    }
9156                    return conn;
9157                }
9158            }
9159            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9160            if (stable) {
9161                conn.stableCount = 1;
9162                conn.numStableIncs = 1;
9163            } else {
9164                conn.unstableCount = 1;
9165                conn.numUnstableIncs = 1;
9166            }
9167            cpr.connections.add(conn);
9168            r.conProviders.add(conn);
9169            return conn;
9170        }
9171        cpr.addExternalProcessHandleLocked(externalProcessToken);
9172        return null;
9173    }
9174
9175    boolean decProviderCountLocked(ContentProviderConnection conn,
9176            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9177        if (conn != null) {
9178            cpr = conn.provider;
9179            if (DEBUG_PROVIDER) Slog.v(TAG,
9180                    "Removing provider requested by "
9181                    + conn.client.processName + " from process "
9182                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9183                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9184            if (stable) {
9185                conn.stableCount--;
9186            } else {
9187                conn.unstableCount--;
9188            }
9189            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9190                cpr.connections.remove(conn);
9191                conn.client.conProviders.remove(conn);
9192                return true;
9193            }
9194            return false;
9195        }
9196        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9197        return false;
9198    }
9199
9200    private void checkTime(long startTime, String where) {
9201        long now = SystemClock.elapsedRealtime();
9202        if ((now-startTime) > 1000) {
9203            // If we are taking more than a second, log about it.
9204            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9205        }
9206    }
9207
9208    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9209            String name, IBinder token, boolean stable, int userId) {
9210        ContentProviderRecord cpr;
9211        ContentProviderConnection conn = null;
9212        ProviderInfo cpi = null;
9213
9214        synchronized(this) {
9215            long startTime = SystemClock.elapsedRealtime();
9216
9217            ProcessRecord r = null;
9218            if (caller != null) {
9219                r = getRecordForAppLocked(caller);
9220                if (r == null) {
9221                    throw new SecurityException(
9222                            "Unable to find app for caller " + caller
9223                          + " (pid=" + Binder.getCallingPid()
9224                          + ") when getting content provider " + name);
9225                }
9226            }
9227
9228            boolean checkCrossUser = true;
9229
9230            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9231
9232            // First check if this content provider has been published...
9233            cpr = mProviderMap.getProviderByName(name, userId);
9234            // If that didn't work, check if it exists for user 0 and then
9235            // verify that it's a singleton provider before using it.
9236            if (cpr == null && userId != UserHandle.USER_OWNER) {
9237                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9238                if (cpr != null) {
9239                    cpi = cpr.info;
9240                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9241                            cpi.name, cpi.flags)
9242                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9243                        userId = UserHandle.USER_OWNER;
9244                        checkCrossUser = false;
9245                    } else {
9246                        cpr = null;
9247                        cpi = null;
9248                    }
9249                }
9250            }
9251
9252            boolean providerRunning = cpr != null;
9253            if (providerRunning) {
9254                cpi = cpr.info;
9255                String msg;
9256                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9257                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9258                        != null) {
9259                    throw new SecurityException(msg);
9260                }
9261                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9262
9263                if (r != null && cpr.canRunHere(r)) {
9264                    // This provider has been published or is in the process
9265                    // of being published...  but it is also allowed to run
9266                    // in the caller's process, so don't make a connection
9267                    // and just let the caller instantiate its own instance.
9268                    ContentProviderHolder holder = cpr.newHolder(null);
9269                    // don't give caller the provider object, it needs
9270                    // to make its own.
9271                    holder.provider = null;
9272                    return holder;
9273                }
9274
9275                final long origId = Binder.clearCallingIdentity();
9276
9277                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9278
9279                // In this case the provider instance already exists, so we can
9280                // return it right away.
9281                conn = incProviderCountLocked(r, cpr, token, stable);
9282                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9283                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9284                        // If this is a perceptible app accessing the provider,
9285                        // make sure to count it as being accessed and thus
9286                        // back up on the LRU list.  This is good because
9287                        // content providers are often expensive to start.
9288                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9289                        updateLruProcessLocked(cpr.proc, false, null);
9290                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9291                    }
9292                }
9293
9294                if (cpr.proc != null) {
9295                    if (false) {
9296                        if (cpr.name.flattenToShortString().equals(
9297                                "com.android.providers.calendar/.CalendarProvider2")) {
9298                            Slog.v(TAG, "****************** KILLING "
9299                                + cpr.name.flattenToShortString());
9300                            Process.killProcess(cpr.proc.pid);
9301                        }
9302                    }
9303                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9304                    boolean success = updateOomAdjLocked(cpr.proc);
9305                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9306                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9307                    // NOTE: there is still a race here where a signal could be
9308                    // pending on the process even though we managed to update its
9309                    // adj level.  Not sure what to do about this, but at least
9310                    // the race is now smaller.
9311                    if (!success) {
9312                        // Uh oh...  it looks like the provider's process
9313                        // has been killed on us.  We need to wait for a new
9314                        // process to be started, and make sure its death
9315                        // doesn't kill our process.
9316                        Slog.i(TAG,
9317                                "Existing provider " + cpr.name.flattenToShortString()
9318                                + " is crashing; detaching " + r);
9319                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9320                        checkTime(startTime, "getContentProviderImpl: before appDied");
9321                        appDiedLocked(cpr.proc);
9322                        checkTime(startTime, "getContentProviderImpl: after appDied");
9323                        if (!lastRef) {
9324                            // This wasn't the last ref our process had on
9325                            // the provider...  we have now been killed, bail.
9326                            return null;
9327                        }
9328                        providerRunning = false;
9329                        conn = null;
9330                    }
9331                }
9332
9333                Binder.restoreCallingIdentity(origId);
9334            }
9335
9336            boolean singleton;
9337            if (!providerRunning) {
9338                try {
9339                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9340                    cpi = AppGlobals.getPackageManager().
9341                        resolveContentProvider(name,
9342                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9343                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9344                } catch (RemoteException ex) {
9345                }
9346                if (cpi == null) {
9347                    return null;
9348                }
9349                // If the provider is a singleton AND
9350                // (it's a call within the same user || the provider is a
9351                // privileged app)
9352                // Then allow connecting to the singleton provider
9353                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9354                        cpi.name, cpi.flags)
9355                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9356                if (singleton) {
9357                    userId = UserHandle.USER_OWNER;
9358                }
9359                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9360                checkTime(startTime, "getContentProviderImpl: got app info for user");
9361
9362                String msg;
9363                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9364                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9365                        != null) {
9366                    throw new SecurityException(msg);
9367                }
9368                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9369
9370                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9371                        && !cpi.processName.equals("system")) {
9372                    // If this content provider does not run in the system
9373                    // process, and the system is not yet ready to run other
9374                    // processes, then fail fast instead of hanging.
9375                    throw new IllegalArgumentException(
9376                            "Attempt to launch content provider before system ready");
9377                }
9378
9379                // Make sure that the user who owns this provider is started.  If not,
9380                // we don't want to allow it to run.
9381                if (mStartedUsers.get(userId) == null) {
9382                    Slog.w(TAG, "Unable to launch app "
9383                            + cpi.applicationInfo.packageName + "/"
9384                            + cpi.applicationInfo.uid + " for provider "
9385                            + name + ": user " + userId + " is stopped");
9386                    return null;
9387                }
9388
9389                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9390                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9391                cpr = mProviderMap.getProviderByClass(comp, userId);
9392                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9393                final boolean firstClass = cpr == null;
9394                if (firstClass) {
9395                    final long ident = Binder.clearCallingIdentity();
9396                    try {
9397                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9398                        ApplicationInfo ai =
9399                            AppGlobals.getPackageManager().
9400                                getApplicationInfo(
9401                                        cpi.applicationInfo.packageName,
9402                                        STOCK_PM_FLAGS, userId);
9403                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9404                        if (ai == null) {
9405                            Slog.w(TAG, "No package info for content provider "
9406                                    + cpi.name);
9407                            return null;
9408                        }
9409                        ai = getAppInfoForUser(ai, userId);
9410                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9411                    } catch (RemoteException ex) {
9412                        // pm is in same process, this will never happen.
9413                    } finally {
9414                        Binder.restoreCallingIdentity(ident);
9415                    }
9416                }
9417
9418                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9419
9420                if (r != null && cpr.canRunHere(r)) {
9421                    // If this is a multiprocess provider, then just return its
9422                    // info and allow the caller to instantiate it.  Only do
9423                    // this if the provider is the same user as the caller's
9424                    // process, or can run as root (so can be in any process).
9425                    return cpr.newHolder(null);
9426                }
9427
9428                if (DEBUG_PROVIDER) {
9429                    RuntimeException e = new RuntimeException("here");
9430                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9431                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9432                }
9433
9434                // This is single process, and our app is now connecting to it.
9435                // See if we are already in the process of launching this
9436                // provider.
9437                final int N = mLaunchingProviders.size();
9438                int i;
9439                for (i=0; i<N; i++) {
9440                    if (mLaunchingProviders.get(i) == cpr) {
9441                        break;
9442                    }
9443                }
9444
9445                // If the provider is not already being launched, then get it
9446                // started.
9447                if (i >= N) {
9448                    final long origId = Binder.clearCallingIdentity();
9449
9450                    try {
9451                        // Content provider is now in use, its package can't be stopped.
9452                        try {
9453                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9454                            AppGlobals.getPackageManager().setPackageStoppedState(
9455                                    cpr.appInfo.packageName, false, userId);
9456                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9457                        } catch (RemoteException e) {
9458                        } catch (IllegalArgumentException e) {
9459                            Slog.w(TAG, "Failed trying to unstop package "
9460                                    + cpr.appInfo.packageName + ": " + e);
9461                        }
9462
9463                        // Use existing process if already started
9464                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9465                        ProcessRecord proc = getProcessRecordLocked(
9466                                cpi.processName, cpr.appInfo.uid, false);
9467                        if (proc != null && proc.thread != null) {
9468                            if (DEBUG_PROVIDER) {
9469                                Slog.d(TAG, "Installing in existing process " + proc);
9470                            }
9471                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9472                            proc.pubProviders.put(cpi.name, cpr);
9473                            try {
9474                                proc.thread.scheduleInstallProvider(cpi);
9475                            } catch (RemoteException e) {
9476                            }
9477                        } else {
9478                            checkTime(startTime, "getContentProviderImpl: before start process");
9479                            proc = startProcessLocked(cpi.processName,
9480                                    cpr.appInfo, false, 0, "content provider",
9481                                    new ComponentName(cpi.applicationInfo.packageName,
9482                                            cpi.name), false, false, false);
9483                            checkTime(startTime, "getContentProviderImpl: after start process");
9484                            if (proc == null) {
9485                                Slog.w(TAG, "Unable to launch app "
9486                                        + cpi.applicationInfo.packageName + "/"
9487                                        + cpi.applicationInfo.uid + " for provider "
9488                                        + name + ": process is bad");
9489                                return null;
9490                            }
9491                        }
9492                        cpr.launchingApp = proc;
9493                        mLaunchingProviders.add(cpr);
9494                    } finally {
9495                        Binder.restoreCallingIdentity(origId);
9496                    }
9497                }
9498
9499                checkTime(startTime, "getContentProviderImpl: updating data structures");
9500
9501                // Make sure the provider is published (the same provider class
9502                // may be published under multiple names).
9503                if (firstClass) {
9504                    mProviderMap.putProviderByClass(comp, cpr);
9505                }
9506
9507                mProviderMap.putProviderByName(name, cpr);
9508                conn = incProviderCountLocked(r, cpr, token, stable);
9509                if (conn != null) {
9510                    conn.waiting = true;
9511                }
9512            }
9513            checkTime(startTime, "getContentProviderImpl: done!");
9514        }
9515
9516        // Wait for the provider to be published...
9517        synchronized (cpr) {
9518            while (cpr.provider == null) {
9519                if (cpr.launchingApp == null) {
9520                    Slog.w(TAG, "Unable to launch app "
9521                            + cpi.applicationInfo.packageName + "/"
9522                            + cpi.applicationInfo.uid + " for provider "
9523                            + name + ": launching app became null");
9524                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9525                            UserHandle.getUserId(cpi.applicationInfo.uid),
9526                            cpi.applicationInfo.packageName,
9527                            cpi.applicationInfo.uid, name);
9528                    return null;
9529                }
9530                try {
9531                    if (DEBUG_MU) {
9532                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9533                                + cpr.launchingApp);
9534                    }
9535                    if (conn != null) {
9536                        conn.waiting = true;
9537                    }
9538                    cpr.wait();
9539                } catch (InterruptedException ex) {
9540                } finally {
9541                    if (conn != null) {
9542                        conn.waiting = false;
9543                    }
9544                }
9545            }
9546        }
9547        return cpr != null ? cpr.newHolder(conn) : null;
9548    }
9549
9550    @Override
9551    public final ContentProviderHolder getContentProvider(
9552            IApplicationThread caller, String name, int userId, boolean stable) {
9553        enforceNotIsolatedCaller("getContentProvider");
9554        if (caller == null) {
9555            String msg = "null IApplicationThread when getting content provider "
9556                    + name;
9557            Slog.w(TAG, msg);
9558            throw new SecurityException(msg);
9559        }
9560        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9561        // with cross-user grant.
9562        return getContentProviderImpl(caller, name, null, stable, userId);
9563    }
9564
9565    public ContentProviderHolder getContentProviderExternal(
9566            String name, int userId, IBinder token) {
9567        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9568            "Do not have permission in call getContentProviderExternal()");
9569        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9570                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9571        return getContentProviderExternalUnchecked(name, token, userId);
9572    }
9573
9574    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9575            IBinder token, int userId) {
9576        return getContentProviderImpl(null, name, token, true, userId);
9577    }
9578
9579    /**
9580     * Drop a content provider from a ProcessRecord's bookkeeping
9581     */
9582    public void removeContentProvider(IBinder connection, boolean stable) {
9583        enforceNotIsolatedCaller("removeContentProvider");
9584        long ident = Binder.clearCallingIdentity();
9585        try {
9586            synchronized (this) {
9587                ContentProviderConnection conn;
9588                try {
9589                    conn = (ContentProviderConnection)connection;
9590                } catch (ClassCastException e) {
9591                    String msg ="removeContentProvider: " + connection
9592                            + " not a ContentProviderConnection";
9593                    Slog.w(TAG, msg);
9594                    throw new IllegalArgumentException(msg);
9595                }
9596                if (conn == null) {
9597                    throw new NullPointerException("connection is null");
9598                }
9599                if (decProviderCountLocked(conn, null, null, stable)) {
9600                    updateOomAdjLocked();
9601                }
9602            }
9603        } finally {
9604            Binder.restoreCallingIdentity(ident);
9605        }
9606    }
9607
9608    public void removeContentProviderExternal(String name, IBinder token) {
9609        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9610            "Do not have permission in call removeContentProviderExternal()");
9611        int userId = UserHandle.getCallingUserId();
9612        long ident = Binder.clearCallingIdentity();
9613        try {
9614            removeContentProviderExternalUnchecked(name, token, userId);
9615        } finally {
9616            Binder.restoreCallingIdentity(ident);
9617        }
9618    }
9619
9620    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9621        synchronized (this) {
9622            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9623            if(cpr == null) {
9624                //remove from mProvidersByClass
9625                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9626                return;
9627            }
9628
9629            //update content provider record entry info
9630            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9631            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9632            if (localCpr.hasExternalProcessHandles()) {
9633                if (localCpr.removeExternalProcessHandleLocked(token)) {
9634                    updateOomAdjLocked();
9635                } else {
9636                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9637                            + " with no external reference for token: "
9638                            + token + ".");
9639                }
9640            } else {
9641                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9642                        + " with no external references.");
9643            }
9644        }
9645    }
9646
9647    public final void publishContentProviders(IApplicationThread caller,
9648            List<ContentProviderHolder> providers) {
9649        if (providers == null) {
9650            return;
9651        }
9652
9653        enforceNotIsolatedCaller("publishContentProviders");
9654        synchronized (this) {
9655            final ProcessRecord r = getRecordForAppLocked(caller);
9656            if (DEBUG_MU)
9657                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9658            if (r == null) {
9659                throw new SecurityException(
9660                        "Unable to find app for caller " + caller
9661                      + " (pid=" + Binder.getCallingPid()
9662                      + ") when publishing content providers");
9663            }
9664
9665            final long origId = Binder.clearCallingIdentity();
9666
9667            final int N = providers.size();
9668            for (int i=0; i<N; i++) {
9669                ContentProviderHolder src = providers.get(i);
9670                if (src == null || src.info == null || src.provider == null) {
9671                    continue;
9672                }
9673                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9674                if (DEBUG_MU)
9675                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9676                if (dst != null) {
9677                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9678                    mProviderMap.putProviderByClass(comp, dst);
9679                    String names[] = dst.info.authority.split(";");
9680                    for (int j = 0; j < names.length; j++) {
9681                        mProviderMap.putProviderByName(names[j], dst);
9682                    }
9683
9684                    int NL = mLaunchingProviders.size();
9685                    int j;
9686                    for (j=0; j<NL; j++) {
9687                        if (mLaunchingProviders.get(j) == dst) {
9688                            mLaunchingProviders.remove(j);
9689                            j--;
9690                            NL--;
9691                        }
9692                    }
9693                    synchronized (dst) {
9694                        dst.provider = src.provider;
9695                        dst.proc = r;
9696                        dst.notifyAll();
9697                    }
9698                    updateOomAdjLocked(r);
9699                }
9700            }
9701
9702            Binder.restoreCallingIdentity(origId);
9703        }
9704    }
9705
9706    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9707        ContentProviderConnection conn;
9708        try {
9709            conn = (ContentProviderConnection)connection;
9710        } catch (ClassCastException e) {
9711            String msg ="refContentProvider: " + connection
9712                    + " not a ContentProviderConnection";
9713            Slog.w(TAG, msg);
9714            throw new IllegalArgumentException(msg);
9715        }
9716        if (conn == null) {
9717            throw new NullPointerException("connection is null");
9718        }
9719
9720        synchronized (this) {
9721            if (stable > 0) {
9722                conn.numStableIncs += stable;
9723            }
9724            stable = conn.stableCount + stable;
9725            if (stable < 0) {
9726                throw new IllegalStateException("stableCount < 0: " + stable);
9727            }
9728
9729            if (unstable > 0) {
9730                conn.numUnstableIncs += unstable;
9731            }
9732            unstable = conn.unstableCount + unstable;
9733            if (unstable < 0) {
9734                throw new IllegalStateException("unstableCount < 0: " + unstable);
9735            }
9736
9737            if ((stable+unstable) <= 0) {
9738                throw new IllegalStateException("ref counts can't go to zero here: stable="
9739                        + stable + " unstable=" + unstable);
9740            }
9741            conn.stableCount = stable;
9742            conn.unstableCount = unstable;
9743            return !conn.dead;
9744        }
9745    }
9746
9747    public void unstableProviderDied(IBinder connection) {
9748        ContentProviderConnection conn;
9749        try {
9750            conn = (ContentProviderConnection)connection;
9751        } catch (ClassCastException e) {
9752            String msg ="refContentProvider: " + connection
9753                    + " not a ContentProviderConnection";
9754            Slog.w(TAG, msg);
9755            throw new IllegalArgumentException(msg);
9756        }
9757        if (conn == null) {
9758            throw new NullPointerException("connection is null");
9759        }
9760
9761        // Safely retrieve the content provider associated with the connection.
9762        IContentProvider provider;
9763        synchronized (this) {
9764            provider = conn.provider.provider;
9765        }
9766
9767        if (provider == null) {
9768            // Um, yeah, we're way ahead of you.
9769            return;
9770        }
9771
9772        // Make sure the caller is being honest with us.
9773        if (provider.asBinder().pingBinder()) {
9774            // Er, no, still looks good to us.
9775            synchronized (this) {
9776                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9777                        + " says " + conn + " died, but we don't agree");
9778                return;
9779            }
9780        }
9781
9782        // Well look at that!  It's dead!
9783        synchronized (this) {
9784            if (conn.provider.provider != provider) {
9785                // But something changed...  good enough.
9786                return;
9787            }
9788
9789            ProcessRecord proc = conn.provider.proc;
9790            if (proc == null || proc.thread == null) {
9791                // Seems like the process is already cleaned up.
9792                return;
9793            }
9794
9795            // As far as we're concerned, this is just like receiving a
9796            // death notification...  just a bit prematurely.
9797            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9798                    + ") early provider death");
9799            final long ident = Binder.clearCallingIdentity();
9800            try {
9801                appDiedLocked(proc);
9802            } finally {
9803                Binder.restoreCallingIdentity(ident);
9804            }
9805        }
9806    }
9807
9808    @Override
9809    public void appNotRespondingViaProvider(IBinder connection) {
9810        enforceCallingPermission(
9811                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9812
9813        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9814        if (conn == null) {
9815            Slog.w(TAG, "ContentProviderConnection is null");
9816            return;
9817        }
9818
9819        final ProcessRecord host = conn.provider.proc;
9820        if (host == null) {
9821            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9822            return;
9823        }
9824
9825        final long token = Binder.clearCallingIdentity();
9826        try {
9827            appNotResponding(host, null, null, false, "ContentProvider not responding");
9828        } finally {
9829            Binder.restoreCallingIdentity(token);
9830        }
9831    }
9832
9833    public final void installSystemProviders() {
9834        List<ProviderInfo> providers;
9835        synchronized (this) {
9836            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9837            providers = generateApplicationProvidersLocked(app);
9838            if (providers != null) {
9839                for (int i=providers.size()-1; i>=0; i--) {
9840                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9841                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9842                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9843                                + ": not system .apk");
9844                        providers.remove(i);
9845                    }
9846                }
9847            }
9848        }
9849        if (providers != null) {
9850            mSystemThread.installSystemProviders(providers);
9851        }
9852
9853        mCoreSettingsObserver = new CoreSettingsObserver(this);
9854
9855        //mUsageStatsService.monitorPackages();
9856    }
9857
9858    /**
9859     * Allows apps to retrieve the MIME type of a URI.
9860     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9861     * users, then it does not need permission to access the ContentProvider.
9862     * Either, it needs cross-user uri grants.
9863     *
9864     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9865     *
9866     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9867     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9868     */
9869    public String getProviderMimeType(Uri uri, int userId) {
9870        enforceNotIsolatedCaller("getProviderMimeType");
9871        final String name = uri.getAuthority();
9872        int callingUid = Binder.getCallingUid();
9873        int callingPid = Binder.getCallingPid();
9874        long ident = 0;
9875        boolean clearedIdentity = false;
9876        userId = unsafeConvertIncomingUser(userId);
9877        if (canClearIdentity(callingPid, callingUid, userId)) {
9878            clearedIdentity = true;
9879            ident = Binder.clearCallingIdentity();
9880        }
9881        ContentProviderHolder holder = null;
9882        try {
9883            holder = getContentProviderExternalUnchecked(name, null, userId);
9884            if (holder != null) {
9885                return holder.provider.getType(uri);
9886            }
9887        } catch (RemoteException e) {
9888            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9889            return null;
9890        } finally {
9891            // We need to clear the identity to call removeContentProviderExternalUnchecked
9892            if (!clearedIdentity) {
9893                ident = Binder.clearCallingIdentity();
9894            }
9895            try {
9896                if (holder != null) {
9897                    removeContentProviderExternalUnchecked(name, null, userId);
9898                }
9899            } finally {
9900                Binder.restoreCallingIdentity(ident);
9901            }
9902        }
9903
9904        return null;
9905    }
9906
9907    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9908        if (UserHandle.getUserId(callingUid) == userId) {
9909            return true;
9910        }
9911        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9912                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9913                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9914                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9915                return true;
9916        }
9917        return false;
9918    }
9919
9920    // =========================================================
9921    // GLOBAL MANAGEMENT
9922    // =========================================================
9923
9924    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9925            boolean isolated, int isolatedUid) {
9926        String proc = customProcess != null ? customProcess : info.processName;
9927        BatteryStatsImpl.Uid.Proc ps = null;
9928        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9929        int uid = info.uid;
9930        if (isolated) {
9931            if (isolatedUid == 0) {
9932                int userId = UserHandle.getUserId(uid);
9933                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9934                while (true) {
9935                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9936                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9937                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9938                    }
9939                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9940                    mNextIsolatedProcessUid++;
9941                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9942                        // No process for this uid, use it.
9943                        break;
9944                    }
9945                    stepsLeft--;
9946                    if (stepsLeft <= 0) {
9947                        return null;
9948                    }
9949                }
9950            } else {
9951                // Special case for startIsolatedProcess (internal only), where
9952                // the uid of the isolated process is specified by the caller.
9953                uid = isolatedUid;
9954            }
9955        }
9956        return new ProcessRecord(stats, info, proc, uid);
9957    }
9958
9959    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9960            String abiOverride) {
9961        ProcessRecord app;
9962        if (!isolated) {
9963            app = getProcessRecordLocked(info.processName, info.uid, true);
9964        } else {
9965            app = null;
9966        }
9967
9968        if (app == null) {
9969            app = newProcessRecordLocked(info, null, isolated, 0);
9970            mProcessNames.put(info.processName, app.uid, app);
9971            if (isolated) {
9972                mIsolatedProcesses.put(app.uid, app);
9973            }
9974            updateLruProcessLocked(app, false, null);
9975            updateOomAdjLocked();
9976        }
9977
9978        // This package really, really can not be stopped.
9979        try {
9980            AppGlobals.getPackageManager().setPackageStoppedState(
9981                    info.packageName, false, UserHandle.getUserId(app.uid));
9982        } catch (RemoteException e) {
9983        } catch (IllegalArgumentException e) {
9984            Slog.w(TAG, "Failed trying to unstop package "
9985                    + info.packageName + ": " + e);
9986        }
9987
9988        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9989                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9990            app.persistent = true;
9991            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9992        }
9993        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9994            mPersistentStartingProcesses.add(app);
9995            startProcessLocked(app, "added application", app.processName, abiOverride,
9996                    null /* entryPoint */, null /* entryPointArgs */);
9997        }
9998
9999        return app;
10000    }
10001
10002    public void unhandledBack() {
10003        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10004                "unhandledBack()");
10005
10006        synchronized(this) {
10007            final long origId = Binder.clearCallingIdentity();
10008            try {
10009                getFocusedStack().unhandledBackLocked();
10010            } finally {
10011                Binder.restoreCallingIdentity(origId);
10012            }
10013        }
10014    }
10015
10016    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10017        enforceNotIsolatedCaller("openContentUri");
10018        final int userId = UserHandle.getCallingUserId();
10019        String name = uri.getAuthority();
10020        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10021        ParcelFileDescriptor pfd = null;
10022        if (cph != null) {
10023            // We record the binder invoker's uid in thread-local storage before
10024            // going to the content provider to open the file.  Later, in the code
10025            // that handles all permissions checks, we look for this uid and use
10026            // that rather than the Activity Manager's own uid.  The effect is that
10027            // we do the check against the caller's permissions even though it looks
10028            // to the content provider like the Activity Manager itself is making
10029            // the request.
10030            sCallerIdentity.set(new Identity(
10031                    Binder.getCallingPid(), Binder.getCallingUid()));
10032            try {
10033                pfd = cph.provider.openFile(null, uri, "r", null);
10034            } catch (FileNotFoundException e) {
10035                // do nothing; pfd will be returned null
10036            } finally {
10037                // Ensure that whatever happens, we clean up the identity state
10038                sCallerIdentity.remove();
10039            }
10040
10041            // We've got the fd now, so we're done with the provider.
10042            removeContentProviderExternalUnchecked(name, null, userId);
10043        } else {
10044            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10045        }
10046        return pfd;
10047    }
10048
10049    // Actually is sleeping or shutting down or whatever else in the future
10050    // is an inactive state.
10051    public boolean isSleepingOrShuttingDown() {
10052        return isSleeping() || mShuttingDown;
10053    }
10054
10055    public boolean isSleeping() {
10056        return mSleeping;
10057    }
10058
10059    void goingToSleep() {
10060        synchronized(this) {
10061            mWentToSleep = true;
10062            goToSleepIfNeededLocked();
10063        }
10064    }
10065
10066    void finishRunningVoiceLocked() {
10067        if (mRunningVoice) {
10068            mRunningVoice = false;
10069            goToSleepIfNeededLocked();
10070        }
10071    }
10072
10073    void goToSleepIfNeededLocked() {
10074        if (mWentToSleep && !mRunningVoice) {
10075            if (!mSleeping) {
10076                mSleeping = true;
10077                mStackSupervisor.goingToSleepLocked();
10078
10079                // Initialize the wake times of all processes.
10080                checkExcessivePowerUsageLocked(false);
10081                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10082                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10083                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10084            }
10085        }
10086    }
10087
10088    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10089        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10090            // Never persist the home stack.
10091            return;
10092        }
10093        mTaskPersister.wakeup(task, flush);
10094    }
10095
10096    @Override
10097    public boolean shutdown(int timeout) {
10098        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10099                != PackageManager.PERMISSION_GRANTED) {
10100            throw new SecurityException("Requires permission "
10101                    + android.Manifest.permission.SHUTDOWN);
10102        }
10103
10104        boolean timedout = false;
10105
10106        synchronized(this) {
10107            mShuttingDown = true;
10108            updateEventDispatchingLocked();
10109            timedout = mStackSupervisor.shutdownLocked(timeout);
10110        }
10111
10112        mAppOpsService.shutdown();
10113        if (mUsageStatsService != null) {
10114            mUsageStatsService.prepareShutdown();
10115        }
10116        mBatteryStatsService.shutdown();
10117        synchronized (this) {
10118            mProcessStats.shutdownLocked();
10119        }
10120        notifyTaskPersisterLocked(null, true);
10121
10122        return timedout;
10123    }
10124
10125    public final void activitySlept(IBinder token) {
10126        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10127
10128        final long origId = Binder.clearCallingIdentity();
10129
10130        synchronized (this) {
10131            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10132            if (r != null) {
10133                mStackSupervisor.activitySleptLocked(r);
10134            }
10135        }
10136
10137        Binder.restoreCallingIdentity(origId);
10138    }
10139
10140    void logLockScreen(String msg) {
10141        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10142                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10143                mWentToSleep + " mSleeping=" + mSleeping);
10144    }
10145
10146    private void comeOutOfSleepIfNeededLocked() {
10147        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10148            if (mSleeping) {
10149                mSleeping = false;
10150                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10151            }
10152        }
10153    }
10154
10155    void wakingUp() {
10156        synchronized(this) {
10157            mWentToSleep = false;
10158            comeOutOfSleepIfNeededLocked();
10159        }
10160    }
10161
10162    void startRunningVoiceLocked() {
10163        if (!mRunningVoice) {
10164            mRunningVoice = true;
10165            comeOutOfSleepIfNeededLocked();
10166        }
10167    }
10168
10169    private void updateEventDispatchingLocked() {
10170        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10171    }
10172
10173    public void setLockScreenShown(boolean shown) {
10174        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10175                != PackageManager.PERMISSION_GRANTED) {
10176            throw new SecurityException("Requires permission "
10177                    + android.Manifest.permission.DEVICE_POWER);
10178        }
10179
10180        synchronized(this) {
10181            long ident = Binder.clearCallingIdentity();
10182            try {
10183                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10184                mLockScreenShown = shown;
10185                comeOutOfSleepIfNeededLocked();
10186            } finally {
10187                Binder.restoreCallingIdentity(ident);
10188            }
10189        }
10190    }
10191
10192    @Override
10193    public void stopAppSwitches() {
10194        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10195                != PackageManager.PERMISSION_GRANTED) {
10196            throw new SecurityException("Requires permission "
10197                    + android.Manifest.permission.STOP_APP_SWITCHES);
10198        }
10199
10200        synchronized(this) {
10201            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10202                    + APP_SWITCH_DELAY_TIME;
10203            mDidAppSwitch = false;
10204            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10205            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10206            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10207        }
10208    }
10209
10210    public void resumeAppSwitches() {
10211        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10212                != PackageManager.PERMISSION_GRANTED) {
10213            throw new SecurityException("Requires permission "
10214                    + android.Manifest.permission.STOP_APP_SWITCHES);
10215        }
10216
10217        synchronized(this) {
10218            // Note that we don't execute any pending app switches... we will
10219            // let those wait until either the timeout, or the next start
10220            // activity request.
10221            mAppSwitchesAllowedTime = 0;
10222        }
10223    }
10224
10225    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10226            int callingPid, int callingUid, String name) {
10227        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10228            return true;
10229        }
10230
10231        int perm = checkComponentPermission(
10232                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10233                sourceUid, -1, true);
10234        if (perm == PackageManager.PERMISSION_GRANTED) {
10235            return true;
10236        }
10237
10238        // If the actual IPC caller is different from the logical source, then
10239        // also see if they are allowed to control app switches.
10240        if (callingUid != -1 && callingUid != sourceUid) {
10241            perm = checkComponentPermission(
10242                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10243                    callingUid, -1, true);
10244            if (perm == PackageManager.PERMISSION_GRANTED) {
10245                return true;
10246            }
10247        }
10248
10249        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10250        return false;
10251    }
10252
10253    public void setDebugApp(String packageName, boolean waitForDebugger,
10254            boolean persistent) {
10255        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10256                "setDebugApp()");
10257
10258        long ident = Binder.clearCallingIdentity();
10259        try {
10260            // Note that this is not really thread safe if there are multiple
10261            // callers into it at the same time, but that's not a situation we
10262            // care about.
10263            if (persistent) {
10264                final ContentResolver resolver = mContext.getContentResolver();
10265                Settings.Global.putString(
10266                    resolver, Settings.Global.DEBUG_APP,
10267                    packageName);
10268                Settings.Global.putInt(
10269                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10270                    waitForDebugger ? 1 : 0);
10271            }
10272
10273            synchronized (this) {
10274                if (!persistent) {
10275                    mOrigDebugApp = mDebugApp;
10276                    mOrigWaitForDebugger = mWaitForDebugger;
10277                }
10278                mDebugApp = packageName;
10279                mWaitForDebugger = waitForDebugger;
10280                mDebugTransient = !persistent;
10281                if (packageName != null) {
10282                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10283                            false, UserHandle.USER_ALL, "set debug app");
10284                }
10285            }
10286        } finally {
10287            Binder.restoreCallingIdentity(ident);
10288        }
10289    }
10290
10291    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10292        synchronized (this) {
10293            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10294            if (!isDebuggable) {
10295                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10296                    throw new SecurityException("Process not debuggable: " + app.packageName);
10297                }
10298            }
10299
10300            mOpenGlTraceApp = processName;
10301        }
10302    }
10303
10304    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10305        synchronized (this) {
10306            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10307            if (!isDebuggable) {
10308                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10309                    throw new SecurityException("Process not debuggable: " + app.packageName);
10310                }
10311            }
10312            mProfileApp = processName;
10313            mProfileFile = profilerInfo.profileFile;
10314            if (mProfileFd != null) {
10315                try {
10316                    mProfileFd.close();
10317                } catch (IOException e) {
10318                }
10319                mProfileFd = null;
10320            }
10321            mProfileFd = profilerInfo.profileFd;
10322            mSamplingInterval = profilerInfo.samplingInterval;
10323            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10324            mProfileType = 0;
10325        }
10326    }
10327
10328    @Override
10329    public void setAlwaysFinish(boolean enabled) {
10330        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10331                "setAlwaysFinish()");
10332
10333        Settings.Global.putInt(
10334                mContext.getContentResolver(),
10335                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10336
10337        synchronized (this) {
10338            mAlwaysFinishActivities = enabled;
10339        }
10340    }
10341
10342    @Override
10343    public void setActivityController(IActivityController controller) {
10344        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10345                "setActivityController()");
10346        synchronized (this) {
10347            mController = controller;
10348            Watchdog.getInstance().setActivityController(controller);
10349        }
10350    }
10351
10352    @Override
10353    public void setUserIsMonkey(boolean userIsMonkey) {
10354        synchronized (this) {
10355            synchronized (mPidsSelfLocked) {
10356                final int callingPid = Binder.getCallingPid();
10357                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10358                if (precessRecord == null) {
10359                    throw new SecurityException("Unknown process: " + callingPid);
10360                }
10361                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10362                    throw new SecurityException("Only an instrumentation process "
10363                            + "with a UiAutomation can call setUserIsMonkey");
10364                }
10365            }
10366            mUserIsMonkey = userIsMonkey;
10367        }
10368    }
10369
10370    @Override
10371    public boolean isUserAMonkey() {
10372        synchronized (this) {
10373            // If there is a controller also implies the user is a monkey.
10374            return (mUserIsMonkey || mController != null);
10375        }
10376    }
10377
10378    public void requestBugReport() {
10379        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10380        SystemProperties.set("ctl.start", "bugreport");
10381    }
10382
10383    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10384        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10385    }
10386
10387    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10388        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10389            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10390        }
10391        return KEY_DISPATCHING_TIMEOUT;
10392    }
10393
10394    @Override
10395    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10396        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10397                != PackageManager.PERMISSION_GRANTED) {
10398            throw new SecurityException("Requires permission "
10399                    + android.Manifest.permission.FILTER_EVENTS);
10400        }
10401        ProcessRecord proc;
10402        long timeout;
10403        synchronized (this) {
10404            synchronized (mPidsSelfLocked) {
10405                proc = mPidsSelfLocked.get(pid);
10406            }
10407            timeout = getInputDispatchingTimeoutLocked(proc);
10408        }
10409
10410        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10411            return -1;
10412        }
10413
10414        return timeout;
10415    }
10416
10417    /**
10418     * Handle input dispatching timeouts.
10419     * Returns whether input dispatching should be aborted or not.
10420     */
10421    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10422            final ActivityRecord activity, final ActivityRecord parent,
10423            final boolean aboveSystem, String reason) {
10424        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10425                != PackageManager.PERMISSION_GRANTED) {
10426            throw new SecurityException("Requires permission "
10427                    + android.Manifest.permission.FILTER_EVENTS);
10428        }
10429
10430        final String annotation;
10431        if (reason == null) {
10432            annotation = "Input dispatching timed out";
10433        } else {
10434            annotation = "Input dispatching timed out (" + reason + ")";
10435        }
10436
10437        if (proc != null) {
10438            synchronized (this) {
10439                if (proc.debugging) {
10440                    return false;
10441                }
10442
10443                if (mDidDexOpt) {
10444                    // Give more time since we were dexopting.
10445                    mDidDexOpt = false;
10446                    return false;
10447                }
10448
10449                if (proc.instrumentationClass != null) {
10450                    Bundle info = new Bundle();
10451                    info.putString("shortMsg", "keyDispatchingTimedOut");
10452                    info.putString("longMsg", annotation);
10453                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10454                    return true;
10455                }
10456            }
10457            mHandler.post(new Runnable() {
10458                @Override
10459                public void run() {
10460                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10461                }
10462            });
10463        }
10464
10465        return true;
10466    }
10467
10468    public Bundle getAssistContextExtras(int requestType) {
10469        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10470                UserHandle.getCallingUserId());
10471        if (pae == null) {
10472            return null;
10473        }
10474        synchronized (pae) {
10475            while (!pae.haveResult) {
10476                try {
10477                    pae.wait();
10478                } catch (InterruptedException e) {
10479                }
10480            }
10481            if (pae.result != null) {
10482                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10483            }
10484        }
10485        synchronized (this) {
10486            mPendingAssistExtras.remove(pae);
10487            mHandler.removeCallbacks(pae);
10488        }
10489        return pae.extras;
10490    }
10491
10492    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10493            int userHandle) {
10494        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10495                "getAssistContextExtras()");
10496        PendingAssistExtras pae;
10497        Bundle extras = new Bundle();
10498        synchronized (this) {
10499            ActivityRecord activity = getFocusedStack().mResumedActivity;
10500            if (activity == null) {
10501                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10502                return null;
10503            }
10504            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10505            if (activity.app == null || activity.app.thread == null) {
10506                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10507                return null;
10508            }
10509            if (activity.app.pid == Binder.getCallingPid()) {
10510                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10511                return null;
10512            }
10513            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10514            try {
10515                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10516                        requestType);
10517                mPendingAssistExtras.add(pae);
10518                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10519            } catch (RemoteException e) {
10520                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10521                return null;
10522            }
10523            return pae;
10524        }
10525    }
10526
10527    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10528        PendingAssistExtras pae = (PendingAssistExtras)token;
10529        synchronized (pae) {
10530            pae.result = extras;
10531            pae.haveResult = true;
10532            pae.notifyAll();
10533            if (pae.intent == null) {
10534                // Caller is just waiting for the result.
10535                return;
10536            }
10537        }
10538
10539        // We are now ready to launch the assist activity.
10540        synchronized (this) {
10541            boolean exists = mPendingAssistExtras.remove(pae);
10542            mHandler.removeCallbacks(pae);
10543            if (!exists) {
10544                // Timed out.
10545                return;
10546            }
10547        }
10548        pae.intent.replaceExtras(extras);
10549        if (pae.hint != null) {
10550            pae.intent.putExtra(pae.hint, true);
10551        }
10552        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10553                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10554                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10555        closeSystemDialogs("assist");
10556        try {
10557            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10558        } catch (ActivityNotFoundException e) {
10559            Slog.w(TAG, "No activity to handle assist action.", e);
10560        }
10561    }
10562
10563    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10564        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10565    }
10566
10567    public void registerProcessObserver(IProcessObserver observer) {
10568        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10569                "registerProcessObserver()");
10570        synchronized (this) {
10571            mProcessObservers.register(observer);
10572        }
10573    }
10574
10575    @Override
10576    public void unregisterProcessObserver(IProcessObserver observer) {
10577        synchronized (this) {
10578            mProcessObservers.unregister(observer);
10579        }
10580    }
10581
10582    @Override
10583    public boolean convertFromTranslucent(IBinder token) {
10584        final long origId = Binder.clearCallingIdentity();
10585        try {
10586            synchronized (this) {
10587                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10588                if (r == null) {
10589                    return false;
10590                }
10591                final boolean translucentChanged = r.changeWindowTranslucency(true);
10592                if (translucentChanged) {
10593                    r.task.stack.releaseBackgroundResources();
10594                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10595                }
10596                mWindowManager.setAppFullscreen(token, true);
10597                return translucentChanged;
10598            }
10599        } finally {
10600            Binder.restoreCallingIdentity(origId);
10601        }
10602    }
10603
10604    @Override
10605    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10606        final long origId = Binder.clearCallingIdentity();
10607        try {
10608            synchronized (this) {
10609                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10610                if (r == null) {
10611                    return false;
10612                }
10613                int index = r.task.mActivities.lastIndexOf(r);
10614                if (index > 0) {
10615                    ActivityRecord under = r.task.mActivities.get(index - 1);
10616                    under.returningOptions = options;
10617                }
10618                final boolean translucentChanged = r.changeWindowTranslucency(false);
10619                if (translucentChanged) {
10620                    r.task.stack.convertToTranslucent(r);
10621                }
10622                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10623                mWindowManager.setAppFullscreen(token, false);
10624                return translucentChanged;
10625            }
10626        } finally {
10627            Binder.restoreCallingIdentity(origId);
10628        }
10629    }
10630
10631    @Override
10632    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10633        final long origId = Binder.clearCallingIdentity();
10634        try {
10635            synchronized (this) {
10636                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10637                if (r != null) {
10638                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10639                }
10640            }
10641            return false;
10642        } finally {
10643            Binder.restoreCallingIdentity(origId);
10644        }
10645    }
10646
10647    @Override
10648    public boolean isBackgroundVisibleBehind(IBinder token) {
10649        final long origId = Binder.clearCallingIdentity();
10650        try {
10651            synchronized (this) {
10652                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10653                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10654                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10655                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10656                return visible;
10657            }
10658        } finally {
10659            Binder.restoreCallingIdentity(origId);
10660        }
10661    }
10662
10663    @Override
10664    public ActivityOptions getActivityOptions(IBinder token) {
10665        final long origId = Binder.clearCallingIdentity();
10666        try {
10667            synchronized (this) {
10668                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10669                if (r != null) {
10670                    final ActivityOptions activityOptions = r.pendingOptions;
10671                    r.pendingOptions = null;
10672                    return activityOptions;
10673                }
10674                return null;
10675            }
10676        } finally {
10677            Binder.restoreCallingIdentity(origId);
10678        }
10679    }
10680
10681    @Override
10682    public void setImmersive(IBinder token, boolean immersive) {
10683        synchronized(this) {
10684            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10685            if (r == null) {
10686                throw new IllegalArgumentException();
10687            }
10688            r.immersive = immersive;
10689
10690            // update associated state if we're frontmost
10691            if (r == mFocusedActivity) {
10692                if (DEBUG_IMMERSIVE) {
10693                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10694                }
10695                applyUpdateLockStateLocked(r);
10696            }
10697        }
10698    }
10699
10700    @Override
10701    public boolean isImmersive(IBinder token) {
10702        synchronized (this) {
10703            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10704            if (r == null) {
10705                throw new IllegalArgumentException();
10706            }
10707            return r.immersive;
10708        }
10709    }
10710
10711    public boolean isTopActivityImmersive() {
10712        enforceNotIsolatedCaller("startActivity");
10713        synchronized (this) {
10714            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10715            return (r != null) ? r.immersive : false;
10716        }
10717    }
10718
10719    @Override
10720    public boolean isTopOfTask(IBinder token) {
10721        synchronized (this) {
10722            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10723            if (r == null) {
10724                throw new IllegalArgumentException();
10725            }
10726            return r.task.getTopActivity() == r;
10727        }
10728    }
10729
10730    public final void enterSafeMode() {
10731        synchronized(this) {
10732            // It only makes sense to do this before the system is ready
10733            // and started launching other packages.
10734            if (!mSystemReady) {
10735                try {
10736                    AppGlobals.getPackageManager().enterSafeMode();
10737                } catch (RemoteException e) {
10738                }
10739            }
10740
10741            mSafeMode = true;
10742        }
10743    }
10744
10745    public final void showSafeModeOverlay() {
10746        View v = LayoutInflater.from(mContext).inflate(
10747                com.android.internal.R.layout.safe_mode, null);
10748        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10749        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10750        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10751        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10752        lp.gravity = Gravity.BOTTOM | Gravity.START;
10753        lp.format = v.getBackground().getOpacity();
10754        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10755                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10756        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10757        ((WindowManager)mContext.getSystemService(
10758                Context.WINDOW_SERVICE)).addView(v, lp);
10759    }
10760
10761    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10762        if (!(sender instanceof PendingIntentRecord)) {
10763            return;
10764        }
10765        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10766        synchronized (stats) {
10767            if (mBatteryStatsService.isOnBattery()) {
10768                mBatteryStatsService.enforceCallingPermission();
10769                PendingIntentRecord rec = (PendingIntentRecord)sender;
10770                int MY_UID = Binder.getCallingUid();
10771                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10772                BatteryStatsImpl.Uid.Pkg pkg =
10773                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10774                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10775                pkg.incWakeupsLocked();
10776            }
10777        }
10778    }
10779
10780    public boolean killPids(int[] pids, String pReason, boolean secure) {
10781        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10782            throw new SecurityException("killPids only available to the system");
10783        }
10784        String reason = (pReason == null) ? "Unknown" : pReason;
10785        // XXX Note: don't acquire main activity lock here, because the window
10786        // manager calls in with its locks held.
10787
10788        boolean killed = false;
10789        synchronized (mPidsSelfLocked) {
10790            int[] types = new int[pids.length];
10791            int worstType = 0;
10792            for (int i=0; i<pids.length; i++) {
10793                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10794                if (proc != null) {
10795                    int type = proc.setAdj;
10796                    types[i] = type;
10797                    if (type > worstType) {
10798                        worstType = type;
10799                    }
10800                }
10801            }
10802
10803            // If the worst oom_adj is somewhere in the cached proc LRU range,
10804            // then constrain it so we will kill all cached procs.
10805            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10806                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10807                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10808            }
10809
10810            // If this is not a secure call, don't let it kill processes that
10811            // are important.
10812            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10813                worstType = ProcessList.SERVICE_ADJ;
10814            }
10815
10816            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10817            for (int i=0; i<pids.length; i++) {
10818                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10819                if (proc == null) {
10820                    continue;
10821                }
10822                int adj = proc.setAdj;
10823                if (adj >= worstType && !proc.killedByAm) {
10824                    proc.kill(reason, true);
10825                    killed = true;
10826                }
10827            }
10828        }
10829        return killed;
10830    }
10831
10832    @Override
10833    public void killUid(int uid, String reason) {
10834        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10835            throw new SecurityException("killUid only available to the system");
10836        }
10837        synchronized (this) {
10838            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10839                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10840                    reason != null ? reason : "kill uid");
10841        }
10842    }
10843
10844    @Override
10845    public boolean killProcessesBelowForeground(String reason) {
10846        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10847            throw new SecurityException("killProcessesBelowForeground() only available to system");
10848        }
10849
10850        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10851    }
10852
10853    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10854        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10855            throw new SecurityException("killProcessesBelowAdj() only available to system");
10856        }
10857
10858        boolean killed = false;
10859        synchronized (mPidsSelfLocked) {
10860            final int size = mPidsSelfLocked.size();
10861            for (int i = 0; i < size; i++) {
10862                final int pid = mPidsSelfLocked.keyAt(i);
10863                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10864                if (proc == null) continue;
10865
10866                final int adj = proc.setAdj;
10867                if (adj > belowAdj && !proc.killedByAm) {
10868                    proc.kill(reason, true);
10869                    killed = true;
10870                }
10871            }
10872        }
10873        return killed;
10874    }
10875
10876    @Override
10877    public void hang(final IBinder who, boolean allowRestart) {
10878        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10879                != PackageManager.PERMISSION_GRANTED) {
10880            throw new SecurityException("Requires permission "
10881                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10882        }
10883
10884        final IBinder.DeathRecipient death = new DeathRecipient() {
10885            @Override
10886            public void binderDied() {
10887                synchronized (this) {
10888                    notifyAll();
10889                }
10890            }
10891        };
10892
10893        try {
10894            who.linkToDeath(death, 0);
10895        } catch (RemoteException e) {
10896            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10897            return;
10898        }
10899
10900        synchronized (this) {
10901            Watchdog.getInstance().setAllowRestart(allowRestart);
10902            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10903            synchronized (death) {
10904                while (who.isBinderAlive()) {
10905                    try {
10906                        death.wait();
10907                    } catch (InterruptedException e) {
10908                    }
10909                }
10910            }
10911            Watchdog.getInstance().setAllowRestart(true);
10912        }
10913    }
10914
10915    @Override
10916    public void restart() {
10917        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10918                != PackageManager.PERMISSION_GRANTED) {
10919            throw new SecurityException("Requires permission "
10920                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10921        }
10922
10923        Log.i(TAG, "Sending shutdown broadcast...");
10924
10925        BroadcastReceiver br = new BroadcastReceiver() {
10926            @Override public void onReceive(Context context, Intent intent) {
10927                // Now the broadcast is done, finish up the low-level shutdown.
10928                Log.i(TAG, "Shutting down activity manager...");
10929                shutdown(10000);
10930                Log.i(TAG, "Shutdown complete, restarting!");
10931                Process.killProcess(Process.myPid());
10932                System.exit(10);
10933            }
10934        };
10935
10936        // First send the high-level shut down broadcast.
10937        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10938        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10939        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10940        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10941        mContext.sendOrderedBroadcastAsUser(intent,
10942                UserHandle.ALL, null, br, mHandler, 0, null, null);
10943        */
10944        br.onReceive(mContext, intent);
10945    }
10946
10947    private long getLowRamTimeSinceIdle(long now) {
10948        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10949    }
10950
10951    @Override
10952    public void performIdleMaintenance() {
10953        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10954                != PackageManager.PERMISSION_GRANTED) {
10955            throw new SecurityException("Requires permission "
10956                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10957        }
10958
10959        synchronized (this) {
10960            final long now = SystemClock.uptimeMillis();
10961            final long timeSinceLastIdle = now - mLastIdleTime;
10962            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10963            mLastIdleTime = now;
10964            mLowRamTimeSinceLastIdle = 0;
10965            if (mLowRamStartTime != 0) {
10966                mLowRamStartTime = now;
10967            }
10968
10969            StringBuilder sb = new StringBuilder(128);
10970            sb.append("Idle maintenance over ");
10971            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10972            sb.append(" low RAM for ");
10973            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10974            Slog.i(TAG, sb.toString());
10975
10976            // If at least 1/3 of our time since the last idle period has been spent
10977            // with RAM low, then we want to kill processes.
10978            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10979
10980            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10981                ProcessRecord proc = mLruProcesses.get(i);
10982                if (proc.notCachedSinceIdle) {
10983                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10984                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10985                        if (doKilling && proc.initialIdlePss != 0
10986                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10987                            proc.kill("idle maint (pss " + proc.lastPss
10988                                    + " from " + proc.initialIdlePss + ")", true);
10989                        }
10990                    }
10991                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10992                    proc.notCachedSinceIdle = true;
10993                    proc.initialIdlePss = 0;
10994                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10995                            isSleeping(), now);
10996                }
10997            }
10998
10999            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11000            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11001        }
11002    }
11003
11004    private void retrieveSettings() {
11005        final ContentResolver resolver = mContext.getContentResolver();
11006        String debugApp = Settings.Global.getString(
11007            resolver, Settings.Global.DEBUG_APP);
11008        boolean waitForDebugger = Settings.Global.getInt(
11009            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11010        boolean alwaysFinishActivities = Settings.Global.getInt(
11011            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11012        boolean forceRtl = Settings.Global.getInt(
11013                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11014        // Transfer any global setting for forcing RTL layout, into a System Property
11015        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11016
11017        Configuration configuration = new Configuration();
11018        Settings.System.getConfiguration(resolver, configuration);
11019        if (forceRtl) {
11020            // This will take care of setting the correct layout direction flags
11021            configuration.setLayoutDirection(configuration.locale);
11022        }
11023
11024        synchronized (this) {
11025            mDebugApp = mOrigDebugApp = debugApp;
11026            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11027            mAlwaysFinishActivities = alwaysFinishActivities;
11028            // This happens before any activities are started, so we can
11029            // change mConfiguration in-place.
11030            updateConfigurationLocked(configuration, null, false, true);
11031            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11032        }
11033    }
11034
11035    /** Loads resources after the current configuration has been set. */
11036    private void loadResourcesOnSystemReady() {
11037        final Resources res = mContext.getResources();
11038        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11039        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11040        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11041    }
11042
11043    public boolean testIsSystemReady() {
11044        // no need to synchronize(this) just to read & return the value
11045        return mSystemReady;
11046    }
11047
11048    private static File getCalledPreBootReceiversFile() {
11049        File dataDir = Environment.getDataDirectory();
11050        File systemDir = new File(dataDir, "system");
11051        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11052        return fname;
11053    }
11054
11055    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11056        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11057        File file = getCalledPreBootReceiversFile();
11058        FileInputStream fis = null;
11059        try {
11060            fis = new FileInputStream(file);
11061            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11062            int fvers = dis.readInt();
11063            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11064                String vers = dis.readUTF();
11065                String codename = dis.readUTF();
11066                String build = dis.readUTF();
11067                if (android.os.Build.VERSION.RELEASE.equals(vers)
11068                        && android.os.Build.VERSION.CODENAME.equals(codename)
11069                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11070                    int num = dis.readInt();
11071                    while (num > 0) {
11072                        num--;
11073                        String pkg = dis.readUTF();
11074                        String cls = dis.readUTF();
11075                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11076                    }
11077                }
11078            }
11079        } catch (FileNotFoundException e) {
11080        } catch (IOException e) {
11081            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11082        } finally {
11083            if (fis != null) {
11084                try {
11085                    fis.close();
11086                } catch (IOException e) {
11087                }
11088            }
11089        }
11090        return lastDoneReceivers;
11091    }
11092
11093    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11094        File file = getCalledPreBootReceiversFile();
11095        FileOutputStream fos = null;
11096        DataOutputStream dos = null;
11097        try {
11098            fos = new FileOutputStream(file);
11099            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11100            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11101            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11102            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11103            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11104            dos.writeInt(list.size());
11105            for (int i=0; i<list.size(); i++) {
11106                dos.writeUTF(list.get(i).getPackageName());
11107                dos.writeUTF(list.get(i).getClassName());
11108            }
11109        } catch (IOException e) {
11110            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11111            file.delete();
11112        } finally {
11113            FileUtils.sync(fos);
11114            if (dos != null) {
11115                try {
11116                    dos.close();
11117                } catch (IOException e) {
11118                    // TODO Auto-generated catch block
11119                    e.printStackTrace();
11120                }
11121            }
11122        }
11123    }
11124
11125    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11126            ArrayList<ComponentName> doneReceivers, int userId) {
11127        boolean waitingUpdate = false;
11128        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11129        List<ResolveInfo> ris = null;
11130        try {
11131            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11132                    intent, null, 0, userId);
11133        } catch (RemoteException e) {
11134        }
11135        if (ris != null) {
11136            for (int i=ris.size()-1; i>=0; i--) {
11137                if ((ris.get(i).activityInfo.applicationInfo.flags
11138                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11139                    ris.remove(i);
11140                }
11141            }
11142            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11143
11144            // For User 0, load the version number. When delivering to a new user, deliver
11145            // to all receivers.
11146            if (userId == UserHandle.USER_OWNER) {
11147                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11148                for (int i=0; i<ris.size(); i++) {
11149                    ActivityInfo ai = ris.get(i).activityInfo;
11150                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11151                    if (lastDoneReceivers.contains(comp)) {
11152                        // We already did the pre boot receiver for this app with the current
11153                        // platform version, so don't do it again...
11154                        ris.remove(i);
11155                        i--;
11156                        // ...however, do keep it as one that has been done, so we don't
11157                        // forget about it when rewriting the file of last done receivers.
11158                        doneReceivers.add(comp);
11159                    }
11160                }
11161            }
11162
11163            // If primary user, send broadcast to all available users, else just to userId
11164            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11165                    : new int[] { userId };
11166            for (int i = 0; i < ris.size(); i++) {
11167                ActivityInfo ai = ris.get(i).activityInfo;
11168                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11169                doneReceivers.add(comp);
11170                intent.setComponent(comp);
11171                for (int j=0; j<users.length; j++) {
11172                    IIntentReceiver finisher = null;
11173                    // On last receiver and user, set up a completion callback
11174                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11175                        finisher = new IIntentReceiver.Stub() {
11176                            public void performReceive(Intent intent, int resultCode,
11177                                    String data, Bundle extras, boolean ordered,
11178                                    boolean sticky, int sendingUser) {
11179                                // The raw IIntentReceiver interface is called
11180                                // with the AM lock held, so redispatch to
11181                                // execute our code without the lock.
11182                                mHandler.post(onFinishCallback);
11183                            }
11184                        };
11185                    }
11186                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11187                            + " for user " + users[j]);
11188                    broadcastIntentLocked(null, null, intent, null, finisher,
11189                            0, null, null, null, AppOpsManager.OP_NONE,
11190                            true, false, MY_PID, Process.SYSTEM_UID,
11191                            users[j]);
11192                    if (finisher != null) {
11193                        waitingUpdate = true;
11194                    }
11195                }
11196            }
11197        }
11198
11199        return waitingUpdate;
11200    }
11201
11202    public void systemReady(final Runnable goingCallback) {
11203        synchronized(this) {
11204            if (mSystemReady) {
11205                // If we're done calling all the receivers, run the next "boot phase" passed in
11206                // by the SystemServer
11207                if (goingCallback != null) {
11208                    goingCallback.run();
11209                }
11210                return;
11211            }
11212
11213            // Make sure we have the current profile info, since it is needed for
11214            // security checks.
11215            updateCurrentProfileIdsLocked();
11216
11217            if (mRecentTasks == null) {
11218                mRecentTasks = mTaskPersister.restoreTasksLocked();
11219                if (!mRecentTasks.isEmpty()) {
11220                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11221                }
11222                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11223                mTaskPersister.startPersisting();
11224            }
11225
11226            // Check to see if there are any update receivers to run.
11227            if (!mDidUpdate) {
11228                if (mWaitingUpdate) {
11229                    return;
11230                }
11231                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11232                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11233                    public void run() {
11234                        synchronized (ActivityManagerService.this) {
11235                            mDidUpdate = true;
11236                        }
11237                        writeLastDonePreBootReceivers(doneReceivers);
11238                        showBootMessage(mContext.getText(
11239                                R.string.android_upgrading_complete),
11240                                false);
11241                        systemReady(goingCallback);
11242                    }
11243                }, doneReceivers, UserHandle.USER_OWNER);
11244
11245                if (mWaitingUpdate) {
11246                    return;
11247                }
11248                mDidUpdate = true;
11249            }
11250
11251            mAppOpsService.systemReady();
11252            mSystemReady = true;
11253        }
11254
11255        ArrayList<ProcessRecord> procsToKill = null;
11256        synchronized(mPidsSelfLocked) {
11257            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11258                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11259                if (!isAllowedWhileBooting(proc.info)){
11260                    if (procsToKill == null) {
11261                        procsToKill = new ArrayList<ProcessRecord>();
11262                    }
11263                    procsToKill.add(proc);
11264                }
11265            }
11266        }
11267
11268        synchronized(this) {
11269            if (procsToKill != null) {
11270                for (int i=procsToKill.size()-1; i>=0; i--) {
11271                    ProcessRecord proc = procsToKill.get(i);
11272                    Slog.i(TAG, "Removing system update proc: " + proc);
11273                    removeProcessLocked(proc, true, false, "system update done");
11274                }
11275            }
11276
11277            // Now that we have cleaned up any update processes, we
11278            // are ready to start launching real processes and know that
11279            // we won't trample on them any more.
11280            mProcessesReady = true;
11281        }
11282
11283        Slog.i(TAG, "System now ready");
11284        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11285            SystemClock.uptimeMillis());
11286
11287        synchronized(this) {
11288            // Make sure we have no pre-ready processes sitting around.
11289
11290            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11291                ResolveInfo ri = mContext.getPackageManager()
11292                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11293                                STOCK_PM_FLAGS);
11294                CharSequence errorMsg = null;
11295                if (ri != null) {
11296                    ActivityInfo ai = ri.activityInfo;
11297                    ApplicationInfo app = ai.applicationInfo;
11298                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11299                        mTopAction = Intent.ACTION_FACTORY_TEST;
11300                        mTopData = null;
11301                        mTopComponent = new ComponentName(app.packageName,
11302                                ai.name);
11303                    } else {
11304                        errorMsg = mContext.getResources().getText(
11305                                com.android.internal.R.string.factorytest_not_system);
11306                    }
11307                } else {
11308                    errorMsg = mContext.getResources().getText(
11309                            com.android.internal.R.string.factorytest_no_action);
11310                }
11311                if (errorMsg != null) {
11312                    mTopAction = null;
11313                    mTopData = null;
11314                    mTopComponent = null;
11315                    Message msg = Message.obtain();
11316                    msg.what = SHOW_FACTORY_ERROR_MSG;
11317                    msg.getData().putCharSequence("msg", errorMsg);
11318                    mHandler.sendMessage(msg);
11319                }
11320            }
11321        }
11322
11323        retrieveSettings();
11324        loadResourcesOnSystemReady();
11325
11326        synchronized (this) {
11327            readGrantedUriPermissionsLocked();
11328        }
11329
11330        if (goingCallback != null) goingCallback.run();
11331
11332        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11333                Integer.toString(mCurrentUserId), mCurrentUserId);
11334        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11335                Integer.toString(mCurrentUserId), mCurrentUserId);
11336        mSystemServiceManager.startUser(mCurrentUserId);
11337
11338        synchronized (this) {
11339            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11340                try {
11341                    List apps = AppGlobals.getPackageManager().
11342                        getPersistentApplications(STOCK_PM_FLAGS);
11343                    if (apps != null) {
11344                        int N = apps.size();
11345                        int i;
11346                        for (i=0; i<N; i++) {
11347                            ApplicationInfo info
11348                                = (ApplicationInfo)apps.get(i);
11349                            if (info != null &&
11350                                    !info.packageName.equals("android")) {
11351                                addAppLocked(info, false, null /* ABI override */);
11352                            }
11353                        }
11354                    }
11355                } catch (RemoteException ex) {
11356                    // pm is in same process, this will never happen.
11357                }
11358            }
11359
11360            // Start up initial activity.
11361            mBooting = true;
11362            startHomeActivityLocked(mCurrentUserId);
11363
11364            try {
11365                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11366                    Message msg = Message.obtain();
11367                    msg.what = SHOW_UID_ERROR_MSG;
11368                    mHandler.sendMessage(msg);
11369                }
11370            } catch (RemoteException e) {
11371            }
11372
11373            long ident = Binder.clearCallingIdentity();
11374            try {
11375                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11376                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11377                        | Intent.FLAG_RECEIVER_FOREGROUND);
11378                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11379                broadcastIntentLocked(null, null, intent,
11380                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11381                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11382                intent = new Intent(Intent.ACTION_USER_STARTING);
11383                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11384                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11385                broadcastIntentLocked(null, null, intent,
11386                        null, new IIntentReceiver.Stub() {
11387                            @Override
11388                            public void performReceive(Intent intent, int resultCode, String data,
11389                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11390                                    throws RemoteException {
11391                            }
11392                        }, 0, null, null,
11393                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11394                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11395            } catch (Throwable t) {
11396                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11397            } finally {
11398                Binder.restoreCallingIdentity(ident);
11399            }
11400            mStackSupervisor.resumeTopActivitiesLocked();
11401            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11402        }
11403    }
11404
11405    private boolean makeAppCrashingLocked(ProcessRecord app,
11406            String shortMsg, String longMsg, String stackTrace) {
11407        app.crashing = true;
11408        app.crashingReport = generateProcessError(app,
11409                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11410        startAppProblemLocked(app);
11411        app.stopFreezingAllLocked();
11412        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11413    }
11414
11415    private void makeAppNotRespondingLocked(ProcessRecord app,
11416            String activity, String shortMsg, String longMsg) {
11417        app.notResponding = true;
11418        app.notRespondingReport = generateProcessError(app,
11419                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11420                activity, shortMsg, longMsg, null);
11421        startAppProblemLocked(app);
11422        app.stopFreezingAllLocked();
11423    }
11424
11425    /**
11426     * Generate a process error record, suitable for attachment to a ProcessRecord.
11427     *
11428     * @param app The ProcessRecord in which the error occurred.
11429     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11430     *                      ActivityManager.AppErrorStateInfo
11431     * @param activity The activity associated with the crash, if known.
11432     * @param shortMsg Short message describing the crash.
11433     * @param longMsg Long message describing the crash.
11434     * @param stackTrace Full crash stack trace, may be null.
11435     *
11436     * @return Returns a fully-formed AppErrorStateInfo record.
11437     */
11438    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11439            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11440        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11441
11442        report.condition = condition;
11443        report.processName = app.processName;
11444        report.pid = app.pid;
11445        report.uid = app.info.uid;
11446        report.tag = activity;
11447        report.shortMsg = shortMsg;
11448        report.longMsg = longMsg;
11449        report.stackTrace = stackTrace;
11450
11451        return report;
11452    }
11453
11454    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11455        synchronized (this) {
11456            app.crashing = false;
11457            app.crashingReport = null;
11458            app.notResponding = false;
11459            app.notRespondingReport = null;
11460            if (app.anrDialog == fromDialog) {
11461                app.anrDialog = null;
11462            }
11463            if (app.waitDialog == fromDialog) {
11464                app.waitDialog = null;
11465            }
11466            if (app.pid > 0 && app.pid != MY_PID) {
11467                handleAppCrashLocked(app, null, null, null);
11468                app.kill("user request after error", true);
11469            }
11470        }
11471    }
11472
11473    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11474            String stackTrace) {
11475        long now = SystemClock.uptimeMillis();
11476
11477        Long crashTime;
11478        if (!app.isolated) {
11479            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11480        } else {
11481            crashTime = null;
11482        }
11483        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11484            // This process loses!
11485            Slog.w(TAG, "Process " + app.info.processName
11486                    + " has crashed too many times: killing!");
11487            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11488                    app.userId, app.info.processName, app.uid);
11489            mStackSupervisor.handleAppCrashLocked(app);
11490            if (!app.persistent) {
11491                // We don't want to start this process again until the user
11492                // explicitly does so...  but for persistent process, we really
11493                // need to keep it running.  If a persistent process is actually
11494                // repeatedly crashing, then badness for everyone.
11495                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11496                        app.info.processName);
11497                if (!app.isolated) {
11498                    // XXX We don't have a way to mark isolated processes
11499                    // as bad, since they don't have a peristent identity.
11500                    mBadProcesses.put(app.info.processName, app.uid,
11501                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11502                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11503                }
11504                app.bad = true;
11505                app.removed = true;
11506                // Don't let services in this process be restarted and potentially
11507                // annoy the user repeatedly.  Unless it is persistent, since those
11508                // processes run critical code.
11509                removeProcessLocked(app, false, false, "crash");
11510                mStackSupervisor.resumeTopActivitiesLocked();
11511                return false;
11512            }
11513            mStackSupervisor.resumeTopActivitiesLocked();
11514        } else {
11515            mStackSupervisor.finishTopRunningActivityLocked(app);
11516        }
11517
11518        // Bump up the crash count of any services currently running in the proc.
11519        for (int i=app.services.size()-1; i>=0; i--) {
11520            // Any services running in the application need to be placed
11521            // back in the pending list.
11522            ServiceRecord sr = app.services.valueAt(i);
11523            sr.crashCount++;
11524        }
11525
11526        // If the crashing process is what we consider to be the "home process" and it has been
11527        // replaced by a third-party app, clear the package preferred activities from packages
11528        // with a home activity running in the process to prevent a repeatedly crashing app
11529        // from blocking the user to manually clear the list.
11530        final ArrayList<ActivityRecord> activities = app.activities;
11531        if (app == mHomeProcess && activities.size() > 0
11532                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11533            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11534                final ActivityRecord r = activities.get(activityNdx);
11535                if (r.isHomeActivity()) {
11536                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11537                    try {
11538                        ActivityThread.getPackageManager()
11539                                .clearPackagePreferredActivities(r.packageName);
11540                    } catch (RemoteException c) {
11541                        // pm is in same process, this will never happen.
11542                    }
11543                }
11544            }
11545        }
11546
11547        if (!app.isolated) {
11548            // XXX Can't keep track of crash times for isolated processes,
11549            // because they don't have a perisistent identity.
11550            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11551        }
11552
11553        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11554        return true;
11555    }
11556
11557    void startAppProblemLocked(ProcessRecord app) {
11558        // If this app is not running under the current user, then we
11559        // can't give it a report button because that would require
11560        // launching the report UI under a different user.
11561        app.errorReportReceiver = null;
11562
11563        for (int userId : mCurrentProfileIds) {
11564            if (app.userId == userId) {
11565                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11566                        mContext, app.info.packageName, app.info.flags);
11567            }
11568        }
11569        skipCurrentReceiverLocked(app);
11570    }
11571
11572    void skipCurrentReceiverLocked(ProcessRecord app) {
11573        for (BroadcastQueue queue : mBroadcastQueues) {
11574            queue.skipCurrentReceiverLocked(app);
11575        }
11576    }
11577
11578    /**
11579     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11580     * The application process will exit immediately after this call returns.
11581     * @param app object of the crashing app, null for the system server
11582     * @param crashInfo describing the exception
11583     */
11584    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11585        ProcessRecord r = findAppProcess(app, "Crash");
11586        final String processName = app == null ? "system_server"
11587                : (r == null ? "unknown" : r.processName);
11588
11589        handleApplicationCrashInner("crash", r, processName, crashInfo);
11590    }
11591
11592    /* Native crash reporting uses this inner version because it needs to be somewhat
11593     * decoupled from the AM-managed cleanup lifecycle
11594     */
11595    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11596            ApplicationErrorReport.CrashInfo crashInfo) {
11597        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11598                UserHandle.getUserId(Binder.getCallingUid()), processName,
11599                r == null ? -1 : r.info.flags,
11600                crashInfo.exceptionClassName,
11601                crashInfo.exceptionMessage,
11602                crashInfo.throwFileName,
11603                crashInfo.throwLineNumber);
11604
11605        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11606
11607        crashApplication(r, crashInfo);
11608    }
11609
11610    public void handleApplicationStrictModeViolation(
11611            IBinder app,
11612            int violationMask,
11613            StrictMode.ViolationInfo info) {
11614        ProcessRecord r = findAppProcess(app, "StrictMode");
11615        if (r == null) {
11616            return;
11617        }
11618
11619        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11620            Integer stackFingerprint = info.hashCode();
11621            boolean logIt = true;
11622            synchronized (mAlreadyLoggedViolatedStacks) {
11623                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11624                    logIt = false;
11625                    // TODO: sub-sample into EventLog for these, with
11626                    // the info.durationMillis?  Then we'd get
11627                    // the relative pain numbers, without logging all
11628                    // the stack traces repeatedly.  We'd want to do
11629                    // likewise in the client code, which also does
11630                    // dup suppression, before the Binder call.
11631                } else {
11632                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11633                        mAlreadyLoggedViolatedStacks.clear();
11634                    }
11635                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11636                }
11637            }
11638            if (logIt) {
11639                logStrictModeViolationToDropBox(r, info);
11640            }
11641        }
11642
11643        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11644            AppErrorResult result = new AppErrorResult();
11645            synchronized (this) {
11646                final long origId = Binder.clearCallingIdentity();
11647
11648                Message msg = Message.obtain();
11649                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11650                HashMap<String, Object> data = new HashMap<String, Object>();
11651                data.put("result", result);
11652                data.put("app", r);
11653                data.put("violationMask", violationMask);
11654                data.put("info", info);
11655                msg.obj = data;
11656                mHandler.sendMessage(msg);
11657
11658                Binder.restoreCallingIdentity(origId);
11659            }
11660            int res = result.get();
11661            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11662        }
11663    }
11664
11665    // Depending on the policy in effect, there could be a bunch of
11666    // these in quick succession so we try to batch these together to
11667    // minimize disk writes, number of dropbox entries, and maximize
11668    // compression, by having more fewer, larger records.
11669    private void logStrictModeViolationToDropBox(
11670            ProcessRecord process,
11671            StrictMode.ViolationInfo info) {
11672        if (info == null) {
11673            return;
11674        }
11675        final boolean isSystemApp = process == null ||
11676                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11677                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11678        final String processName = process == null ? "unknown" : process.processName;
11679        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11680        final DropBoxManager dbox = (DropBoxManager)
11681                mContext.getSystemService(Context.DROPBOX_SERVICE);
11682
11683        // Exit early if the dropbox isn't configured to accept this report type.
11684        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11685
11686        boolean bufferWasEmpty;
11687        boolean needsFlush;
11688        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11689        synchronized (sb) {
11690            bufferWasEmpty = sb.length() == 0;
11691            appendDropBoxProcessHeaders(process, processName, sb);
11692            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11693            sb.append("System-App: ").append(isSystemApp).append("\n");
11694            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11695            if (info.violationNumThisLoop != 0) {
11696                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11697            }
11698            if (info.numAnimationsRunning != 0) {
11699                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11700            }
11701            if (info.broadcastIntentAction != null) {
11702                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11703            }
11704            if (info.durationMillis != -1) {
11705                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11706            }
11707            if (info.numInstances != -1) {
11708                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11709            }
11710            if (info.tags != null) {
11711                for (String tag : info.tags) {
11712                    sb.append("Span-Tag: ").append(tag).append("\n");
11713                }
11714            }
11715            sb.append("\n");
11716            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11717                sb.append(info.crashInfo.stackTrace);
11718            }
11719            sb.append("\n");
11720
11721            // Only buffer up to ~64k.  Various logging bits truncate
11722            // things at 128k.
11723            needsFlush = (sb.length() > 64 * 1024);
11724        }
11725
11726        // Flush immediately if the buffer's grown too large, or this
11727        // is a non-system app.  Non-system apps are isolated with a
11728        // different tag & policy and not batched.
11729        //
11730        // Batching is useful during internal testing with
11731        // StrictMode settings turned up high.  Without batching,
11732        // thousands of separate files could be created on boot.
11733        if (!isSystemApp || needsFlush) {
11734            new Thread("Error dump: " + dropboxTag) {
11735                @Override
11736                public void run() {
11737                    String report;
11738                    synchronized (sb) {
11739                        report = sb.toString();
11740                        sb.delete(0, sb.length());
11741                        sb.trimToSize();
11742                    }
11743                    if (report.length() != 0) {
11744                        dbox.addText(dropboxTag, report);
11745                    }
11746                }
11747            }.start();
11748            return;
11749        }
11750
11751        // System app batching:
11752        if (!bufferWasEmpty) {
11753            // An existing dropbox-writing thread is outstanding, so
11754            // we don't need to start it up.  The existing thread will
11755            // catch the buffer appends we just did.
11756            return;
11757        }
11758
11759        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11760        // (After this point, we shouldn't access AMS internal data structures.)
11761        new Thread("Error dump: " + dropboxTag) {
11762            @Override
11763            public void run() {
11764                // 5 second sleep to let stacks arrive and be batched together
11765                try {
11766                    Thread.sleep(5000);  // 5 seconds
11767                } catch (InterruptedException e) {}
11768
11769                String errorReport;
11770                synchronized (mStrictModeBuffer) {
11771                    errorReport = mStrictModeBuffer.toString();
11772                    if (errorReport.length() == 0) {
11773                        return;
11774                    }
11775                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11776                    mStrictModeBuffer.trimToSize();
11777                }
11778                dbox.addText(dropboxTag, errorReport);
11779            }
11780        }.start();
11781    }
11782
11783    /**
11784     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11785     * @param app object of the crashing app, null for the system server
11786     * @param tag reported by the caller
11787     * @param system whether this wtf is coming from the system
11788     * @param crashInfo describing the context of the error
11789     * @return true if the process should exit immediately (WTF is fatal)
11790     */
11791    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11792            final ApplicationErrorReport.CrashInfo crashInfo) {
11793        final int callingUid = Binder.getCallingUid();
11794        final int callingPid = Binder.getCallingPid();
11795
11796        if (system) {
11797            // If this is coming from the system, we could very well have low-level
11798            // system locks held, so we want to do this all asynchronously.  And we
11799            // never want this to become fatal, so there is that too.
11800            mHandler.post(new Runnable() {
11801                @Override public void run() {
11802                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11803                }
11804            });
11805            return false;
11806        }
11807
11808        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11809                crashInfo);
11810
11811        if (r != null && r.pid != Process.myPid() &&
11812                Settings.Global.getInt(mContext.getContentResolver(),
11813                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11814            crashApplication(r, crashInfo);
11815            return true;
11816        } else {
11817            return false;
11818        }
11819    }
11820
11821    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11822            final ApplicationErrorReport.CrashInfo crashInfo) {
11823        final ProcessRecord r = findAppProcess(app, "WTF");
11824        final String processName = app == null ? "system_server"
11825                : (r == null ? "unknown" : r.processName);
11826
11827        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11828                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11829
11830        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11831
11832        return r;
11833    }
11834
11835    /**
11836     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11837     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11838     */
11839    private ProcessRecord findAppProcess(IBinder app, String reason) {
11840        if (app == null) {
11841            return null;
11842        }
11843
11844        synchronized (this) {
11845            final int NP = mProcessNames.getMap().size();
11846            for (int ip=0; ip<NP; ip++) {
11847                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11848                final int NA = apps.size();
11849                for (int ia=0; ia<NA; ia++) {
11850                    ProcessRecord p = apps.valueAt(ia);
11851                    if (p.thread != null && p.thread.asBinder() == app) {
11852                        return p;
11853                    }
11854                }
11855            }
11856
11857            Slog.w(TAG, "Can't find mystery application for " + reason
11858                    + " from pid=" + Binder.getCallingPid()
11859                    + " uid=" + Binder.getCallingUid() + ": " + app);
11860            return null;
11861        }
11862    }
11863
11864    /**
11865     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11866     * to append various headers to the dropbox log text.
11867     */
11868    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11869            StringBuilder sb) {
11870        // Watchdog thread ends up invoking this function (with
11871        // a null ProcessRecord) to add the stack file to dropbox.
11872        // Do not acquire a lock on this (am) in such cases, as it
11873        // could cause a potential deadlock, if and when watchdog
11874        // is invoked due to unavailability of lock on am and it
11875        // would prevent watchdog from killing system_server.
11876        if (process == null) {
11877            sb.append("Process: ").append(processName).append("\n");
11878            return;
11879        }
11880        // Note: ProcessRecord 'process' is guarded by the service
11881        // instance.  (notably process.pkgList, which could otherwise change
11882        // concurrently during execution of this method)
11883        synchronized (this) {
11884            sb.append("Process: ").append(processName).append("\n");
11885            int flags = process.info.flags;
11886            IPackageManager pm = AppGlobals.getPackageManager();
11887            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11888            for (int ip=0; ip<process.pkgList.size(); ip++) {
11889                String pkg = process.pkgList.keyAt(ip);
11890                sb.append("Package: ").append(pkg);
11891                try {
11892                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11893                    if (pi != null) {
11894                        sb.append(" v").append(pi.versionCode);
11895                        if (pi.versionName != null) {
11896                            sb.append(" (").append(pi.versionName).append(")");
11897                        }
11898                    }
11899                } catch (RemoteException e) {
11900                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11901                }
11902                sb.append("\n");
11903            }
11904        }
11905    }
11906
11907    private static String processClass(ProcessRecord process) {
11908        if (process == null || process.pid == MY_PID) {
11909            return "system_server";
11910        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11911            return "system_app";
11912        } else {
11913            return "data_app";
11914        }
11915    }
11916
11917    /**
11918     * Write a description of an error (crash, WTF, ANR) to the drop box.
11919     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11920     * @param process which caused the error, null means the system server
11921     * @param activity which triggered the error, null if unknown
11922     * @param parent activity related to the error, null if unknown
11923     * @param subject line related to the error, null if absent
11924     * @param report in long form describing the error, null if absent
11925     * @param logFile to include in the report, null if none
11926     * @param crashInfo giving an application stack trace, null if absent
11927     */
11928    public void addErrorToDropBox(String eventType,
11929            ProcessRecord process, String processName, ActivityRecord activity,
11930            ActivityRecord parent, String subject,
11931            final String report, final File logFile,
11932            final ApplicationErrorReport.CrashInfo crashInfo) {
11933        // NOTE -- this must never acquire the ActivityManagerService lock,
11934        // otherwise the watchdog may be prevented from resetting the system.
11935
11936        final String dropboxTag = processClass(process) + "_" + eventType;
11937        final DropBoxManager dbox = (DropBoxManager)
11938                mContext.getSystemService(Context.DROPBOX_SERVICE);
11939
11940        // Exit early if the dropbox isn't configured to accept this report type.
11941        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11942
11943        final StringBuilder sb = new StringBuilder(1024);
11944        appendDropBoxProcessHeaders(process, processName, sb);
11945        if (activity != null) {
11946            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11947        }
11948        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11949            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11950        }
11951        if (parent != null && parent != activity) {
11952            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11953        }
11954        if (subject != null) {
11955            sb.append("Subject: ").append(subject).append("\n");
11956        }
11957        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11958        if (Debug.isDebuggerConnected()) {
11959            sb.append("Debugger: Connected\n");
11960        }
11961        sb.append("\n");
11962
11963        // Do the rest in a worker thread to avoid blocking the caller on I/O
11964        // (After this point, we shouldn't access AMS internal data structures.)
11965        Thread worker = new Thread("Error dump: " + dropboxTag) {
11966            @Override
11967            public void run() {
11968                if (report != null) {
11969                    sb.append(report);
11970                }
11971                if (logFile != null) {
11972                    try {
11973                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11974                                    "\n\n[[TRUNCATED]]"));
11975                    } catch (IOException e) {
11976                        Slog.e(TAG, "Error reading " + logFile, e);
11977                    }
11978                }
11979                if (crashInfo != null && crashInfo.stackTrace != null) {
11980                    sb.append(crashInfo.stackTrace);
11981                }
11982
11983                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11984                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11985                if (lines > 0) {
11986                    sb.append("\n");
11987
11988                    // Merge several logcat streams, and take the last N lines
11989                    InputStreamReader input = null;
11990                    try {
11991                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11992                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11993                                "-b", "crash",
11994                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11995
11996                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11997                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11998                        input = new InputStreamReader(logcat.getInputStream());
11999
12000                        int num;
12001                        char[] buf = new char[8192];
12002                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12003                    } catch (IOException e) {
12004                        Slog.e(TAG, "Error running logcat", e);
12005                    } finally {
12006                        if (input != null) try { input.close(); } catch (IOException e) {}
12007                    }
12008                }
12009
12010                dbox.addText(dropboxTag, sb.toString());
12011            }
12012        };
12013
12014        if (process == null) {
12015            // If process is null, we are being called from some internal code
12016            // and may be about to die -- run this synchronously.
12017            worker.run();
12018        } else {
12019            worker.start();
12020        }
12021    }
12022
12023    /**
12024     * Bring up the "unexpected error" dialog box for a crashing app.
12025     * Deal with edge cases (intercepts from instrumented applications,
12026     * ActivityController, error intent receivers, that sort of thing).
12027     * @param r the application crashing
12028     * @param crashInfo describing the failure
12029     */
12030    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12031        long timeMillis = System.currentTimeMillis();
12032        String shortMsg = crashInfo.exceptionClassName;
12033        String longMsg = crashInfo.exceptionMessage;
12034        String stackTrace = crashInfo.stackTrace;
12035        if (shortMsg != null && longMsg != null) {
12036            longMsg = shortMsg + ": " + longMsg;
12037        } else if (shortMsg != null) {
12038            longMsg = shortMsg;
12039        }
12040
12041        AppErrorResult result = new AppErrorResult();
12042        synchronized (this) {
12043            if (mController != null) {
12044                try {
12045                    String name = r != null ? r.processName : null;
12046                    int pid = r != null ? r.pid : Binder.getCallingPid();
12047                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12048                    if (!mController.appCrashed(name, pid,
12049                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12050                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12051                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12052                            Slog.w(TAG, "Skip killing native crashed app " + name
12053                                    + "(" + pid + ") during testing");
12054                        } else {
12055                            Slog.w(TAG, "Force-killing crashed app " + name
12056                                    + " at watcher's request");
12057                            if (r != null) {
12058                                r.kill("crash", true);
12059                            } else {
12060                                // Huh.
12061                                Process.killProcess(pid);
12062                                Process.killProcessGroup(uid, pid);
12063                            }
12064                        }
12065                        return;
12066                    }
12067                } catch (RemoteException e) {
12068                    mController = null;
12069                    Watchdog.getInstance().setActivityController(null);
12070                }
12071            }
12072
12073            final long origId = Binder.clearCallingIdentity();
12074
12075            // If this process is running instrumentation, finish it.
12076            if (r != null && r.instrumentationClass != null) {
12077                Slog.w(TAG, "Error in app " + r.processName
12078                      + " running instrumentation " + r.instrumentationClass + ":");
12079                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12080                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12081                Bundle info = new Bundle();
12082                info.putString("shortMsg", shortMsg);
12083                info.putString("longMsg", longMsg);
12084                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12085                Binder.restoreCallingIdentity(origId);
12086                return;
12087            }
12088
12089            // If we can't identify the process or it's already exceeded its crash quota,
12090            // quit right away without showing a crash dialog.
12091            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12092                Binder.restoreCallingIdentity(origId);
12093                return;
12094            }
12095
12096            Message msg = Message.obtain();
12097            msg.what = SHOW_ERROR_MSG;
12098            HashMap data = new HashMap();
12099            data.put("result", result);
12100            data.put("app", r);
12101            msg.obj = data;
12102            mHandler.sendMessage(msg);
12103
12104            Binder.restoreCallingIdentity(origId);
12105        }
12106
12107        int res = result.get();
12108
12109        Intent appErrorIntent = null;
12110        synchronized (this) {
12111            if (r != null && !r.isolated) {
12112                // XXX Can't keep track of crash time for isolated processes,
12113                // since they don't have a persistent identity.
12114                mProcessCrashTimes.put(r.info.processName, r.uid,
12115                        SystemClock.uptimeMillis());
12116            }
12117            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12118                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12119            }
12120        }
12121
12122        if (appErrorIntent != null) {
12123            try {
12124                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12125            } catch (ActivityNotFoundException e) {
12126                Slog.w(TAG, "bug report receiver dissappeared", e);
12127            }
12128        }
12129    }
12130
12131    Intent createAppErrorIntentLocked(ProcessRecord r,
12132            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12133        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12134        if (report == null) {
12135            return null;
12136        }
12137        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12138        result.setComponent(r.errorReportReceiver);
12139        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12140        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12141        return result;
12142    }
12143
12144    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12145            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12146        if (r.errorReportReceiver == null) {
12147            return null;
12148        }
12149
12150        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12151            return null;
12152        }
12153
12154        ApplicationErrorReport report = new ApplicationErrorReport();
12155        report.packageName = r.info.packageName;
12156        report.installerPackageName = r.errorReportReceiver.getPackageName();
12157        report.processName = r.processName;
12158        report.time = timeMillis;
12159        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12160
12161        if (r.crashing || r.forceCrashReport) {
12162            report.type = ApplicationErrorReport.TYPE_CRASH;
12163            report.crashInfo = crashInfo;
12164        } else if (r.notResponding) {
12165            report.type = ApplicationErrorReport.TYPE_ANR;
12166            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12167
12168            report.anrInfo.activity = r.notRespondingReport.tag;
12169            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12170            report.anrInfo.info = r.notRespondingReport.longMsg;
12171        }
12172
12173        return report;
12174    }
12175
12176    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12177        enforceNotIsolatedCaller("getProcessesInErrorState");
12178        // assume our apps are happy - lazy create the list
12179        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12180
12181        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12182                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12183        int userId = UserHandle.getUserId(Binder.getCallingUid());
12184
12185        synchronized (this) {
12186
12187            // iterate across all processes
12188            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12189                ProcessRecord app = mLruProcesses.get(i);
12190                if (!allUsers && app.userId != userId) {
12191                    continue;
12192                }
12193                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12194                    // This one's in trouble, so we'll generate a report for it
12195                    // crashes are higher priority (in case there's a crash *and* an anr)
12196                    ActivityManager.ProcessErrorStateInfo report = null;
12197                    if (app.crashing) {
12198                        report = app.crashingReport;
12199                    } else if (app.notResponding) {
12200                        report = app.notRespondingReport;
12201                    }
12202
12203                    if (report != null) {
12204                        if (errList == null) {
12205                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12206                        }
12207                        errList.add(report);
12208                    } else {
12209                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12210                                " crashing = " + app.crashing +
12211                                " notResponding = " + app.notResponding);
12212                    }
12213                }
12214            }
12215        }
12216
12217        return errList;
12218    }
12219
12220    static int procStateToImportance(int procState, int memAdj,
12221            ActivityManager.RunningAppProcessInfo currApp) {
12222        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12223        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12224            currApp.lru = memAdj;
12225        } else {
12226            currApp.lru = 0;
12227        }
12228        return imp;
12229    }
12230
12231    private void fillInProcMemInfo(ProcessRecord app,
12232            ActivityManager.RunningAppProcessInfo outInfo) {
12233        outInfo.pid = app.pid;
12234        outInfo.uid = app.info.uid;
12235        if (mHeavyWeightProcess == app) {
12236            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12237        }
12238        if (app.persistent) {
12239            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12240        }
12241        if (app.activities.size() > 0) {
12242            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12243        }
12244        outInfo.lastTrimLevel = app.trimMemoryLevel;
12245        int adj = app.curAdj;
12246        int procState = app.curProcState;
12247        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12248        outInfo.importanceReasonCode = app.adjTypeCode;
12249        outInfo.processState = app.curProcState;
12250    }
12251
12252    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12253        enforceNotIsolatedCaller("getRunningAppProcesses");
12254        // Lazy instantiation of list
12255        List<ActivityManager.RunningAppProcessInfo> runList = null;
12256        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12257                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12258        int userId = UserHandle.getUserId(Binder.getCallingUid());
12259        synchronized (this) {
12260            // Iterate across all processes
12261            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12262                ProcessRecord app = mLruProcesses.get(i);
12263                if (!allUsers && app.userId != userId) {
12264                    continue;
12265                }
12266                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12267                    // Generate process state info for running application
12268                    ActivityManager.RunningAppProcessInfo currApp =
12269                        new ActivityManager.RunningAppProcessInfo(app.processName,
12270                                app.pid, app.getPackageList());
12271                    fillInProcMemInfo(app, currApp);
12272                    if (app.adjSource instanceof ProcessRecord) {
12273                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12274                        currApp.importanceReasonImportance =
12275                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12276                                        app.adjSourceProcState);
12277                    } else if (app.adjSource instanceof ActivityRecord) {
12278                        ActivityRecord r = (ActivityRecord)app.adjSource;
12279                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12280                    }
12281                    if (app.adjTarget instanceof ComponentName) {
12282                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12283                    }
12284                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12285                    //        + " lru=" + currApp.lru);
12286                    if (runList == null) {
12287                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12288                    }
12289                    runList.add(currApp);
12290                }
12291            }
12292        }
12293        return runList;
12294    }
12295
12296    public List<ApplicationInfo> getRunningExternalApplications() {
12297        enforceNotIsolatedCaller("getRunningExternalApplications");
12298        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12299        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12300        if (runningApps != null && runningApps.size() > 0) {
12301            Set<String> extList = new HashSet<String>();
12302            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12303                if (app.pkgList != null) {
12304                    for (String pkg : app.pkgList) {
12305                        extList.add(pkg);
12306                    }
12307                }
12308            }
12309            IPackageManager pm = AppGlobals.getPackageManager();
12310            for (String pkg : extList) {
12311                try {
12312                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12313                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12314                        retList.add(info);
12315                    }
12316                } catch (RemoteException e) {
12317                }
12318            }
12319        }
12320        return retList;
12321    }
12322
12323    @Override
12324    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12325        enforceNotIsolatedCaller("getMyMemoryState");
12326        synchronized (this) {
12327            ProcessRecord proc;
12328            synchronized (mPidsSelfLocked) {
12329                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12330            }
12331            fillInProcMemInfo(proc, outInfo);
12332        }
12333    }
12334
12335    @Override
12336    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12337        if (checkCallingPermission(android.Manifest.permission.DUMP)
12338                != PackageManager.PERMISSION_GRANTED) {
12339            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12340                    + Binder.getCallingPid()
12341                    + ", uid=" + Binder.getCallingUid()
12342                    + " without permission "
12343                    + android.Manifest.permission.DUMP);
12344            return;
12345        }
12346
12347        boolean dumpAll = false;
12348        boolean dumpClient = false;
12349        String dumpPackage = null;
12350
12351        int opti = 0;
12352        while (opti < args.length) {
12353            String opt = args[opti];
12354            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12355                break;
12356            }
12357            opti++;
12358            if ("-a".equals(opt)) {
12359                dumpAll = true;
12360            } else if ("-c".equals(opt)) {
12361                dumpClient = true;
12362            } else if ("-h".equals(opt)) {
12363                pw.println("Activity manager dump options:");
12364                pw.println("  [-a] [-c] [-h] [cmd] ...");
12365                pw.println("  cmd may be one of:");
12366                pw.println("    a[ctivities]: activity stack state");
12367                pw.println("    r[recents]: recent activities state");
12368                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12369                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12370                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12371                pw.println("    o[om]: out of memory management");
12372                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12373                pw.println("    provider [COMP_SPEC]: provider client-side state");
12374                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12375                pw.println("    service [COMP_SPEC]: service client-side state");
12376                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12377                pw.println("    all: dump all activities");
12378                pw.println("    top: dump the top activity");
12379                pw.println("    write: write all pending state to storage");
12380                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12381                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12382                pw.println("    a partial substring in a component name, a");
12383                pw.println("    hex object identifier.");
12384                pw.println("  -a: include all available server state.");
12385                pw.println("  -c: include client state.");
12386                return;
12387            } else {
12388                pw.println("Unknown argument: " + opt + "; use -h for help");
12389            }
12390        }
12391
12392        long origId = Binder.clearCallingIdentity();
12393        boolean more = false;
12394        // Is the caller requesting to dump a particular piece of data?
12395        if (opti < args.length) {
12396            String cmd = args[opti];
12397            opti++;
12398            if ("activities".equals(cmd) || "a".equals(cmd)) {
12399                synchronized (this) {
12400                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12401                }
12402            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12403                synchronized (this) {
12404                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12405                }
12406            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12407                String[] newArgs;
12408                String name;
12409                if (opti >= args.length) {
12410                    name = null;
12411                    newArgs = EMPTY_STRING_ARRAY;
12412                } else {
12413                    name = args[opti];
12414                    opti++;
12415                    newArgs = new String[args.length - opti];
12416                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12417                            args.length - opti);
12418                }
12419                synchronized (this) {
12420                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12421                }
12422            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12423                String[] newArgs;
12424                String name;
12425                if (opti >= args.length) {
12426                    name = null;
12427                    newArgs = EMPTY_STRING_ARRAY;
12428                } else {
12429                    name = args[opti];
12430                    opti++;
12431                    newArgs = new String[args.length - opti];
12432                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12433                            args.length - opti);
12434                }
12435                synchronized (this) {
12436                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12437                }
12438            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12439                String[] newArgs;
12440                String name;
12441                if (opti >= args.length) {
12442                    name = null;
12443                    newArgs = EMPTY_STRING_ARRAY;
12444                } else {
12445                    name = args[opti];
12446                    opti++;
12447                    newArgs = new String[args.length - opti];
12448                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12449                            args.length - opti);
12450                }
12451                synchronized (this) {
12452                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12453                }
12454            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12455                synchronized (this) {
12456                    dumpOomLocked(fd, pw, args, opti, true);
12457                }
12458            } else if ("provider".equals(cmd)) {
12459                String[] newArgs;
12460                String name;
12461                if (opti >= args.length) {
12462                    name = null;
12463                    newArgs = EMPTY_STRING_ARRAY;
12464                } else {
12465                    name = args[opti];
12466                    opti++;
12467                    newArgs = new String[args.length - opti];
12468                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12469                }
12470                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12471                    pw.println("No providers match: " + name);
12472                    pw.println("Use -h for help.");
12473                }
12474            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12475                synchronized (this) {
12476                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12477                }
12478            } else if ("service".equals(cmd)) {
12479                String[] newArgs;
12480                String name;
12481                if (opti >= args.length) {
12482                    name = null;
12483                    newArgs = EMPTY_STRING_ARRAY;
12484                } else {
12485                    name = args[opti];
12486                    opti++;
12487                    newArgs = new String[args.length - opti];
12488                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12489                            args.length - opti);
12490                }
12491                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12492                    pw.println("No services match: " + name);
12493                    pw.println("Use -h for help.");
12494                }
12495            } else if ("package".equals(cmd)) {
12496                String[] newArgs;
12497                if (opti >= args.length) {
12498                    pw.println("package: no package name specified");
12499                    pw.println("Use -h for help.");
12500                } else {
12501                    dumpPackage = args[opti];
12502                    opti++;
12503                    newArgs = new String[args.length - opti];
12504                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12505                            args.length - opti);
12506                    args = newArgs;
12507                    opti = 0;
12508                    more = true;
12509                }
12510            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12511                synchronized (this) {
12512                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12513                }
12514            } else if ("write".equals(cmd)) {
12515                mTaskPersister.flush();
12516                pw.println("All tasks persisted.");
12517                return;
12518            } else {
12519                // Dumping a single activity?
12520                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12521                    pw.println("Bad activity command, or no activities match: " + cmd);
12522                    pw.println("Use -h for help.");
12523                }
12524            }
12525            if (!more) {
12526                Binder.restoreCallingIdentity(origId);
12527                return;
12528            }
12529        }
12530
12531        // No piece of data specified, dump everything.
12532        synchronized (this) {
12533            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12534            pw.println();
12535            if (dumpAll) {
12536                pw.println("-------------------------------------------------------------------------------");
12537            }
12538            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12539            pw.println();
12540            if (dumpAll) {
12541                pw.println("-------------------------------------------------------------------------------");
12542            }
12543            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12544            pw.println();
12545            if (dumpAll) {
12546                pw.println("-------------------------------------------------------------------------------");
12547            }
12548            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12549            pw.println();
12550            if (dumpAll) {
12551                pw.println("-------------------------------------------------------------------------------");
12552            }
12553            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12554            pw.println();
12555            if (dumpAll) {
12556                pw.println("-------------------------------------------------------------------------------");
12557            }
12558            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12559            pw.println();
12560            if (dumpAll) {
12561                pw.println("-------------------------------------------------------------------------------");
12562            }
12563            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12564        }
12565        Binder.restoreCallingIdentity(origId);
12566    }
12567
12568    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12569            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12570        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12571
12572        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12573                dumpPackage);
12574        boolean needSep = printedAnything;
12575
12576        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12577                dumpPackage, needSep, "  mFocusedActivity: ");
12578        if (printed) {
12579            printedAnything = true;
12580            needSep = false;
12581        }
12582
12583        if (dumpPackage == null) {
12584            if (needSep) {
12585                pw.println();
12586            }
12587            needSep = true;
12588            printedAnything = true;
12589            mStackSupervisor.dump(pw, "  ");
12590        }
12591
12592        if (!printedAnything) {
12593            pw.println("  (nothing)");
12594        }
12595    }
12596
12597    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12598            int opti, boolean dumpAll, String dumpPackage) {
12599        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12600
12601        boolean printedAnything = false;
12602
12603        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12604            boolean printedHeader = false;
12605
12606            final int N = mRecentTasks.size();
12607            for (int i=0; i<N; i++) {
12608                TaskRecord tr = mRecentTasks.get(i);
12609                if (dumpPackage != null) {
12610                    if (tr.realActivity == null ||
12611                            !dumpPackage.equals(tr.realActivity)) {
12612                        continue;
12613                    }
12614                }
12615                if (!printedHeader) {
12616                    pw.println("  Recent tasks:");
12617                    printedHeader = true;
12618                    printedAnything = true;
12619                }
12620                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12621                        pw.println(tr);
12622                if (dumpAll) {
12623                    mRecentTasks.get(i).dump(pw, "    ");
12624                }
12625            }
12626        }
12627
12628        if (!printedAnything) {
12629            pw.println("  (nothing)");
12630        }
12631    }
12632
12633    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12634            int opti, boolean dumpAll, String dumpPackage) {
12635        boolean needSep = false;
12636        boolean printedAnything = false;
12637        int numPers = 0;
12638
12639        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12640
12641        if (dumpAll) {
12642            final int NP = mProcessNames.getMap().size();
12643            for (int ip=0; ip<NP; ip++) {
12644                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12645                final int NA = procs.size();
12646                for (int ia=0; ia<NA; ia++) {
12647                    ProcessRecord r = procs.valueAt(ia);
12648                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12649                        continue;
12650                    }
12651                    if (!needSep) {
12652                        pw.println("  All known processes:");
12653                        needSep = true;
12654                        printedAnything = true;
12655                    }
12656                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12657                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12658                        pw.print(" "); pw.println(r);
12659                    r.dump(pw, "    ");
12660                    if (r.persistent) {
12661                        numPers++;
12662                    }
12663                }
12664            }
12665        }
12666
12667        if (mIsolatedProcesses.size() > 0) {
12668            boolean printed = false;
12669            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12670                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12671                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12672                    continue;
12673                }
12674                if (!printed) {
12675                    if (needSep) {
12676                        pw.println();
12677                    }
12678                    pw.println("  Isolated process list (sorted by uid):");
12679                    printedAnything = true;
12680                    printed = true;
12681                    needSep = true;
12682                }
12683                pw.println(String.format("%sIsolated #%2d: %s",
12684                        "    ", i, r.toString()));
12685            }
12686        }
12687
12688        if (mLruProcesses.size() > 0) {
12689            if (needSep) {
12690                pw.println();
12691            }
12692            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12693                    pw.print(" total, non-act at ");
12694                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12695                    pw.print(", non-svc at ");
12696                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12697                    pw.println("):");
12698            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12699            needSep = true;
12700            printedAnything = true;
12701        }
12702
12703        if (dumpAll || dumpPackage != null) {
12704            synchronized (mPidsSelfLocked) {
12705                boolean printed = false;
12706                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12707                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12708                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12709                        continue;
12710                    }
12711                    if (!printed) {
12712                        if (needSep) pw.println();
12713                        needSep = true;
12714                        pw.println("  PID mappings:");
12715                        printed = true;
12716                        printedAnything = true;
12717                    }
12718                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12719                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12720                }
12721            }
12722        }
12723
12724        if (mForegroundProcesses.size() > 0) {
12725            synchronized (mPidsSelfLocked) {
12726                boolean printed = false;
12727                for (int i=0; i<mForegroundProcesses.size(); i++) {
12728                    ProcessRecord r = mPidsSelfLocked.get(
12729                            mForegroundProcesses.valueAt(i).pid);
12730                    if (dumpPackage != null && (r == null
12731                            || !r.pkgList.containsKey(dumpPackage))) {
12732                        continue;
12733                    }
12734                    if (!printed) {
12735                        if (needSep) pw.println();
12736                        needSep = true;
12737                        pw.println("  Foreground Processes:");
12738                        printed = true;
12739                        printedAnything = true;
12740                    }
12741                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12742                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12743                }
12744            }
12745        }
12746
12747        if (mPersistentStartingProcesses.size() > 0) {
12748            if (needSep) pw.println();
12749            needSep = true;
12750            printedAnything = true;
12751            pw.println("  Persisent processes that are starting:");
12752            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12753                    "Starting Norm", "Restarting PERS", dumpPackage);
12754        }
12755
12756        if (mRemovedProcesses.size() > 0) {
12757            if (needSep) pw.println();
12758            needSep = true;
12759            printedAnything = true;
12760            pw.println("  Processes that are being removed:");
12761            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12762                    "Removed Norm", "Removed PERS", dumpPackage);
12763        }
12764
12765        if (mProcessesOnHold.size() > 0) {
12766            if (needSep) pw.println();
12767            needSep = true;
12768            printedAnything = true;
12769            pw.println("  Processes that are on old until the system is ready:");
12770            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12771                    "OnHold Norm", "OnHold PERS", dumpPackage);
12772        }
12773
12774        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12775
12776        if (mProcessCrashTimes.getMap().size() > 0) {
12777            boolean printed = false;
12778            long now = SystemClock.uptimeMillis();
12779            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12780            final int NP = pmap.size();
12781            for (int ip=0; ip<NP; ip++) {
12782                String pname = pmap.keyAt(ip);
12783                SparseArray<Long> uids = pmap.valueAt(ip);
12784                final int N = uids.size();
12785                for (int i=0; i<N; i++) {
12786                    int puid = uids.keyAt(i);
12787                    ProcessRecord r = mProcessNames.get(pname, puid);
12788                    if (dumpPackage != null && (r == null
12789                            || !r.pkgList.containsKey(dumpPackage))) {
12790                        continue;
12791                    }
12792                    if (!printed) {
12793                        if (needSep) pw.println();
12794                        needSep = true;
12795                        pw.println("  Time since processes crashed:");
12796                        printed = true;
12797                        printedAnything = true;
12798                    }
12799                    pw.print("    Process "); pw.print(pname);
12800                            pw.print(" uid "); pw.print(puid);
12801                            pw.print(": last crashed ");
12802                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12803                            pw.println(" ago");
12804                }
12805            }
12806        }
12807
12808        if (mBadProcesses.getMap().size() > 0) {
12809            boolean printed = false;
12810            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12811            final int NP = pmap.size();
12812            for (int ip=0; ip<NP; ip++) {
12813                String pname = pmap.keyAt(ip);
12814                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12815                final int N = uids.size();
12816                for (int i=0; i<N; i++) {
12817                    int puid = uids.keyAt(i);
12818                    ProcessRecord r = mProcessNames.get(pname, puid);
12819                    if (dumpPackage != null && (r == null
12820                            || !r.pkgList.containsKey(dumpPackage))) {
12821                        continue;
12822                    }
12823                    if (!printed) {
12824                        if (needSep) pw.println();
12825                        needSep = true;
12826                        pw.println("  Bad processes:");
12827                        printedAnything = true;
12828                    }
12829                    BadProcessInfo info = uids.valueAt(i);
12830                    pw.print("    Bad process "); pw.print(pname);
12831                            pw.print(" uid "); pw.print(puid);
12832                            pw.print(": crashed at time "); pw.println(info.time);
12833                    if (info.shortMsg != null) {
12834                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12835                    }
12836                    if (info.longMsg != null) {
12837                        pw.print("      Long msg: "); pw.println(info.longMsg);
12838                    }
12839                    if (info.stack != null) {
12840                        pw.println("      Stack:");
12841                        int lastPos = 0;
12842                        for (int pos=0; pos<info.stack.length(); pos++) {
12843                            if (info.stack.charAt(pos) == '\n') {
12844                                pw.print("        ");
12845                                pw.write(info.stack, lastPos, pos-lastPos);
12846                                pw.println();
12847                                lastPos = pos+1;
12848                            }
12849                        }
12850                        if (lastPos < info.stack.length()) {
12851                            pw.print("        ");
12852                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12853                            pw.println();
12854                        }
12855                    }
12856                }
12857            }
12858        }
12859
12860        if (dumpPackage == null) {
12861            pw.println();
12862            needSep = false;
12863            pw.println("  mStartedUsers:");
12864            for (int i=0; i<mStartedUsers.size(); i++) {
12865                UserStartedState uss = mStartedUsers.valueAt(i);
12866                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12867                        pw.print(": "); uss.dump("", pw);
12868            }
12869            pw.print("  mStartedUserArray: [");
12870            for (int i=0; i<mStartedUserArray.length; i++) {
12871                if (i > 0) pw.print(", ");
12872                pw.print(mStartedUserArray[i]);
12873            }
12874            pw.println("]");
12875            pw.print("  mUserLru: [");
12876            for (int i=0; i<mUserLru.size(); i++) {
12877                if (i > 0) pw.print(", ");
12878                pw.print(mUserLru.get(i));
12879            }
12880            pw.println("]");
12881            if (dumpAll) {
12882                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12883            }
12884            synchronized (mUserProfileGroupIdsSelfLocked) {
12885                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12886                    pw.println("  mUserProfileGroupIds:");
12887                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12888                        pw.print("    User #");
12889                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12890                        pw.print(" -> profile #");
12891                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12892                    }
12893                }
12894            }
12895        }
12896        if (mHomeProcess != null && (dumpPackage == null
12897                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12898            if (needSep) {
12899                pw.println();
12900                needSep = false;
12901            }
12902            pw.println("  mHomeProcess: " + mHomeProcess);
12903        }
12904        if (mPreviousProcess != null && (dumpPackage == null
12905                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12906            if (needSep) {
12907                pw.println();
12908                needSep = false;
12909            }
12910            pw.println("  mPreviousProcess: " + mPreviousProcess);
12911        }
12912        if (dumpAll) {
12913            StringBuilder sb = new StringBuilder(128);
12914            sb.append("  mPreviousProcessVisibleTime: ");
12915            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12916            pw.println(sb);
12917        }
12918        if (mHeavyWeightProcess != null && (dumpPackage == null
12919                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12920            if (needSep) {
12921                pw.println();
12922                needSep = false;
12923            }
12924            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12925        }
12926        if (dumpPackage == null) {
12927            pw.println("  mConfiguration: " + mConfiguration);
12928        }
12929        if (dumpAll) {
12930            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12931            if (mCompatModePackages.getPackages().size() > 0) {
12932                boolean printed = false;
12933                for (Map.Entry<String, Integer> entry
12934                        : mCompatModePackages.getPackages().entrySet()) {
12935                    String pkg = entry.getKey();
12936                    int mode = entry.getValue();
12937                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12938                        continue;
12939                    }
12940                    if (!printed) {
12941                        pw.println("  mScreenCompatPackages:");
12942                        printed = true;
12943                    }
12944                    pw.print("    "); pw.print(pkg); pw.print(": ");
12945                            pw.print(mode); pw.println();
12946                }
12947            }
12948        }
12949        if (dumpPackage == null) {
12950            if (mSleeping || mWentToSleep || mLockScreenShown) {
12951                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12952                        + " mLockScreenShown " + mLockScreenShown);
12953            }
12954            if (mShuttingDown || mRunningVoice) {
12955                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12956            }
12957        }
12958        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12959                || mOrigWaitForDebugger) {
12960            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12961                    || dumpPackage.equals(mOrigDebugApp)) {
12962                if (needSep) {
12963                    pw.println();
12964                    needSep = false;
12965                }
12966                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12967                        + " mDebugTransient=" + mDebugTransient
12968                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12969            }
12970        }
12971        if (mOpenGlTraceApp != null) {
12972            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12973                if (needSep) {
12974                    pw.println();
12975                    needSep = false;
12976                }
12977                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12978            }
12979        }
12980        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12981                || mProfileFd != null) {
12982            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12983                if (needSep) {
12984                    pw.println();
12985                    needSep = false;
12986                }
12987                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12988                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12989                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12990                        + mAutoStopProfiler);
12991                pw.println("  mProfileType=" + mProfileType);
12992            }
12993        }
12994        if (dumpPackage == null) {
12995            if (mAlwaysFinishActivities || mController != null) {
12996                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12997                        + " mController=" + mController);
12998            }
12999            if (dumpAll) {
13000                pw.println("  Total persistent processes: " + numPers);
13001                pw.println("  mProcessesReady=" + mProcessesReady
13002                        + " mSystemReady=" + mSystemReady
13003                        + " mBooted=" + mBooted
13004                        + " mFactoryTest=" + mFactoryTest);
13005                pw.println("  mBooting=" + mBooting
13006                        + " mCallFinishBooting=" + mCallFinishBooting
13007                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13008                pw.print("  mLastPowerCheckRealtime=");
13009                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13010                        pw.println("");
13011                pw.print("  mLastPowerCheckUptime=");
13012                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13013                        pw.println("");
13014                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13015                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13016                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13017                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13018                        + " (" + mLruProcesses.size() + " total)"
13019                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13020                        + " mNumServiceProcs=" + mNumServiceProcs
13021                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13022                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13023                        + " mLastMemoryLevel" + mLastMemoryLevel
13024                        + " mLastNumProcesses" + mLastNumProcesses);
13025                long now = SystemClock.uptimeMillis();
13026                pw.print("  mLastIdleTime=");
13027                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13028                        pw.print(" mLowRamSinceLastIdle=");
13029                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13030                        pw.println();
13031            }
13032        }
13033
13034        if (!printedAnything) {
13035            pw.println("  (nothing)");
13036        }
13037    }
13038
13039    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13040            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13041        if (mProcessesToGc.size() > 0) {
13042            boolean printed = false;
13043            long now = SystemClock.uptimeMillis();
13044            for (int i=0; i<mProcessesToGc.size(); i++) {
13045                ProcessRecord proc = mProcessesToGc.get(i);
13046                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13047                    continue;
13048                }
13049                if (!printed) {
13050                    if (needSep) pw.println();
13051                    needSep = true;
13052                    pw.println("  Processes that are waiting to GC:");
13053                    printed = true;
13054                }
13055                pw.print("    Process "); pw.println(proc);
13056                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13057                        pw.print(", last gced=");
13058                        pw.print(now-proc.lastRequestedGc);
13059                        pw.print(" ms ago, last lowMem=");
13060                        pw.print(now-proc.lastLowMemory);
13061                        pw.println(" ms ago");
13062
13063            }
13064        }
13065        return needSep;
13066    }
13067
13068    void printOomLevel(PrintWriter pw, String name, int adj) {
13069        pw.print("    ");
13070        if (adj >= 0) {
13071            pw.print(' ');
13072            if (adj < 10) pw.print(' ');
13073        } else {
13074            if (adj > -10) pw.print(' ');
13075        }
13076        pw.print(adj);
13077        pw.print(": ");
13078        pw.print(name);
13079        pw.print(" (");
13080        pw.print(mProcessList.getMemLevel(adj)/1024);
13081        pw.println(" kB)");
13082    }
13083
13084    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13085            int opti, boolean dumpAll) {
13086        boolean needSep = false;
13087
13088        if (mLruProcesses.size() > 0) {
13089            if (needSep) pw.println();
13090            needSep = true;
13091            pw.println("  OOM levels:");
13092            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13093            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13094            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13095            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13096            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13097            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13098            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13099            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13100            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13101            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13102            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13103            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13104            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13105            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13106
13107            if (needSep) pw.println();
13108            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13109                    pw.print(" total, non-act at ");
13110                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13111                    pw.print(", non-svc at ");
13112                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13113                    pw.println("):");
13114            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13115            needSep = true;
13116        }
13117
13118        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13119
13120        pw.println();
13121        pw.println("  mHomeProcess: " + mHomeProcess);
13122        pw.println("  mPreviousProcess: " + mPreviousProcess);
13123        if (mHeavyWeightProcess != null) {
13124            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13125        }
13126
13127        return true;
13128    }
13129
13130    /**
13131     * There are three ways to call this:
13132     *  - no provider specified: dump all the providers
13133     *  - a flattened component name that matched an existing provider was specified as the
13134     *    first arg: dump that one provider
13135     *  - the first arg isn't the flattened component name of an existing provider:
13136     *    dump all providers whose component contains the first arg as a substring
13137     */
13138    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13139            int opti, boolean dumpAll) {
13140        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13141    }
13142
13143    static class ItemMatcher {
13144        ArrayList<ComponentName> components;
13145        ArrayList<String> strings;
13146        ArrayList<Integer> objects;
13147        boolean all;
13148
13149        ItemMatcher() {
13150            all = true;
13151        }
13152
13153        void build(String name) {
13154            ComponentName componentName = ComponentName.unflattenFromString(name);
13155            if (componentName != null) {
13156                if (components == null) {
13157                    components = new ArrayList<ComponentName>();
13158                }
13159                components.add(componentName);
13160                all = false;
13161            } else {
13162                int objectId = 0;
13163                // Not a '/' separated full component name; maybe an object ID?
13164                try {
13165                    objectId = Integer.parseInt(name, 16);
13166                    if (objects == null) {
13167                        objects = new ArrayList<Integer>();
13168                    }
13169                    objects.add(objectId);
13170                    all = false;
13171                } catch (RuntimeException e) {
13172                    // Not an integer; just do string match.
13173                    if (strings == null) {
13174                        strings = new ArrayList<String>();
13175                    }
13176                    strings.add(name);
13177                    all = false;
13178                }
13179            }
13180        }
13181
13182        int build(String[] args, int opti) {
13183            for (; opti<args.length; opti++) {
13184                String name = args[opti];
13185                if ("--".equals(name)) {
13186                    return opti+1;
13187                }
13188                build(name);
13189            }
13190            return opti;
13191        }
13192
13193        boolean match(Object object, ComponentName comp) {
13194            if (all) {
13195                return true;
13196            }
13197            if (components != null) {
13198                for (int i=0; i<components.size(); i++) {
13199                    if (components.get(i).equals(comp)) {
13200                        return true;
13201                    }
13202                }
13203            }
13204            if (objects != null) {
13205                for (int i=0; i<objects.size(); i++) {
13206                    if (System.identityHashCode(object) == objects.get(i)) {
13207                        return true;
13208                    }
13209                }
13210            }
13211            if (strings != null) {
13212                String flat = comp.flattenToString();
13213                for (int i=0; i<strings.size(); i++) {
13214                    if (flat.contains(strings.get(i))) {
13215                        return true;
13216                    }
13217                }
13218            }
13219            return false;
13220        }
13221    }
13222
13223    /**
13224     * There are three things that cmd can be:
13225     *  - a flattened component name that matches an existing activity
13226     *  - the cmd arg isn't the flattened component name of an existing activity:
13227     *    dump all activity whose component contains the cmd as a substring
13228     *  - A hex number of the ActivityRecord object instance.
13229     */
13230    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13231            int opti, boolean dumpAll) {
13232        ArrayList<ActivityRecord> activities;
13233
13234        synchronized (this) {
13235            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13236        }
13237
13238        if (activities.size() <= 0) {
13239            return false;
13240        }
13241
13242        String[] newArgs = new String[args.length - opti];
13243        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13244
13245        TaskRecord lastTask = null;
13246        boolean needSep = false;
13247        for (int i=activities.size()-1; i>=0; i--) {
13248            ActivityRecord r = activities.get(i);
13249            if (needSep) {
13250                pw.println();
13251            }
13252            needSep = true;
13253            synchronized (this) {
13254                if (lastTask != r.task) {
13255                    lastTask = r.task;
13256                    pw.print("TASK "); pw.print(lastTask.affinity);
13257                            pw.print(" id="); pw.println(lastTask.taskId);
13258                    if (dumpAll) {
13259                        lastTask.dump(pw, "  ");
13260                    }
13261                }
13262            }
13263            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13264        }
13265        return true;
13266    }
13267
13268    /**
13269     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13270     * there is a thread associated with the activity.
13271     */
13272    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13273            final ActivityRecord r, String[] args, boolean dumpAll) {
13274        String innerPrefix = prefix + "  ";
13275        synchronized (this) {
13276            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13277                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13278                    pw.print(" pid=");
13279                    if (r.app != null) pw.println(r.app.pid);
13280                    else pw.println("(not running)");
13281            if (dumpAll) {
13282                r.dump(pw, innerPrefix);
13283            }
13284        }
13285        if (r.app != null && r.app.thread != null) {
13286            // flush anything that is already in the PrintWriter since the thread is going
13287            // to write to the file descriptor directly
13288            pw.flush();
13289            try {
13290                TransferPipe tp = new TransferPipe();
13291                try {
13292                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13293                            r.appToken, innerPrefix, args);
13294                    tp.go(fd);
13295                } finally {
13296                    tp.kill();
13297                }
13298            } catch (IOException e) {
13299                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13300            } catch (RemoteException e) {
13301                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13302            }
13303        }
13304    }
13305
13306    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13307            int opti, boolean dumpAll, String dumpPackage) {
13308        boolean needSep = false;
13309        boolean onlyHistory = false;
13310        boolean printedAnything = false;
13311
13312        if ("history".equals(dumpPackage)) {
13313            if (opti < args.length && "-s".equals(args[opti])) {
13314                dumpAll = false;
13315            }
13316            onlyHistory = true;
13317            dumpPackage = null;
13318        }
13319
13320        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13321        if (!onlyHistory && dumpAll) {
13322            if (mRegisteredReceivers.size() > 0) {
13323                boolean printed = false;
13324                Iterator it = mRegisteredReceivers.values().iterator();
13325                while (it.hasNext()) {
13326                    ReceiverList r = (ReceiverList)it.next();
13327                    if (dumpPackage != null && (r.app == null ||
13328                            !dumpPackage.equals(r.app.info.packageName))) {
13329                        continue;
13330                    }
13331                    if (!printed) {
13332                        pw.println("  Registered Receivers:");
13333                        needSep = true;
13334                        printed = true;
13335                        printedAnything = true;
13336                    }
13337                    pw.print("  * "); pw.println(r);
13338                    r.dump(pw, "    ");
13339                }
13340            }
13341
13342            if (mReceiverResolver.dump(pw, needSep ?
13343                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13344                    "    ", dumpPackage, false)) {
13345                needSep = true;
13346                printedAnything = true;
13347            }
13348        }
13349
13350        for (BroadcastQueue q : mBroadcastQueues) {
13351            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13352            printedAnything |= needSep;
13353        }
13354
13355        needSep = true;
13356
13357        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13358            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13359                if (needSep) {
13360                    pw.println();
13361                }
13362                needSep = true;
13363                printedAnything = true;
13364                pw.print("  Sticky broadcasts for user ");
13365                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13366                StringBuilder sb = new StringBuilder(128);
13367                for (Map.Entry<String, ArrayList<Intent>> ent
13368                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13369                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13370                    if (dumpAll) {
13371                        pw.println(":");
13372                        ArrayList<Intent> intents = ent.getValue();
13373                        final int N = intents.size();
13374                        for (int i=0; i<N; i++) {
13375                            sb.setLength(0);
13376                            sb.append("    Intent: ");
13377                            intents.get(i).toShortString(sb, false, true, false, false);
13378                            pw.println(sb.toString());
13379                            Bundle bundle = intents.get(i).getExtras();
13380                            if (bundle != null) {
13381                                pw.print("      ");
13382                                pw.println(bundle.toString());
13383                            }
13384                        }
13385                    } else {
13386                        pw.println("");
13387                    }
13388                }
13389            }
13390        }
13391
13392        if (!onlyHistory && dumpAll) {
13393            pw.println();
13394            for (BroadcastQueue queue : mBroadcastQueues) {
13395                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13396                        + queue.mBroadcastsScheduled);
13397            }
13398            pw.println("  mHandler:");
13399            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13400            needSep = true;
13401            printedAnything = true;
13402        }
13403
13404        if (!printedAnything) {
13405            pw.println("  (nothing)");
13406        }
13407    }
13408
13409    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13410            int opti, boolean dumpAll, String dumpPackage) {
13411        boolean needSep;
13412        boolean printedAnything = false;
13413
13414        ItemMatcher matcher = new ItemMatcher();
13415        matcher.build(args, opti);
13416
13417        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13418
13419        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13420        printedAnything |= needSep;
13421
13422        if (mLaunchingProviders.size() > 0) {
13423            boolean printed = false;
13424            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13425                ContentProviderRecord r = mLaunchingProviders.get(i);
13426                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13427                    continue;
13428                }
13429                if (!printed) {
13430                    if (needSep) pw.println();
13431                    needSep = true;
13432                    pw.println("  Launching content providers:");
13433                    printed = true;
13434                    printedAnything = true;
13435                }
13436                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13437                        pw.println(r);
13438            }
13439        }
13440
13441        if (mGrantedUriPermissions.size() > 0) {
13442            boolean printed = false;
13443            int dumpUid = -2;
13444            if (dumpPackage != null) {
13445                try {
13446                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13447                } catch (NameNotFoundException e) {
13448                    dumpUid = -1;
13449                }
13450            }
13451            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13452                int uid = mGrantedUriPermissions.keyAt(i);
13453                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13454                    continue;
13455                }
13456                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13457                if (!printed) {
13458                    if (needSep) pw.println();
13459                    needSep = true;
13460                    pw.println("  Granted Uri Permissions:");
13461                    printed = true;
13462                    printedAnything = true;
13463                }
13464                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13465                for (UriPermission perm : perms.values()) {
13466                    pw.print("    "); pw.println(perm);
13467                    if (dumpAll) {
13468                        perm.dump(pw, "      ");
13469                    }
13470                }
13471            }
13472        }
13473
13474        if (!printedAnything) {
13475            pw.println("  (nothing)");
13476        }
13477    }
13478
13479    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13480            int opti, boolean dumpAll, String dumpPackage) {
13481        boolean printed = false;
13482
13483        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13484
13485        if (mIntentSenderRecords.size() > 0) {
13486            Iterator<WeakReference<PendingIntentRecord>> it
13487                    = mIntentSenderRecords.values().iterator();
13488            while (it.hasNext()) {
13489                WeakReference<PendingIntentRecord> ref = it.next();
13490                PendingIntentRecord rec = ref != null ? ref.get(): null;
13491                if (dumpPackage != null && (rec == null
13492                        || !dumpPackage.equals(rec.key.packageName))) {
13493                    continue;
13494                }
13495                printed = true;
13496                if (rec != null) {
13497                    pw.print("  * "); pw.println(rec);
13498                    if (dumpAll) {
13499                        rec.dump(pw, "    ");
13500                    }
13501                } else {
13502                    pw.print("  * "); pw.println(ref);
13503                }
13504            }
13505        }
13506
13507        if (!printed) {
13508            pw.println("  (nothing)");
13509        }
13510    }
13511
13512    private static final int dumpProcessList(PrintWriter pw,
13513            ActivityManagerService service, List list,
13514            String prefix, String normalLabel, String persistentLabel,
13515            String dumpPackage) {
13516        int numPers = 0;
13517        final int N = list.size()-1;
13518        for (int i=N; i>=0; i--) {
13519            ProcessRecord r = (ProcessRecord)list.get(i);
13520            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13521                continue;
13522            }
13523            pw.println(String.format("%s%s #%2d: %s",
13524                    prefix, (r.persistent ? persistentLabel : normalLabel),
13525                    i, r.toString()));
13526            if (r.persistent) {
13527                numPers++;
13528            }
13529        }
13530        return numPers;
13531    }
13532
13533    private static final boolean dumpProcessOomList(PrintWriter pw,
13534            ActivityManagerService service, List<ProcessRecord> origList,
13535            String prefix, String normalLabel, String persistentLabel,
13536            boolean inclDetails, String dumpPackage) {
13537
13538        ArrayList<Pair<ProcessRecord, Integer>> list
13539                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13540        for (int i=0; i<origList.size(); i++) {
13541            ProcessRecord r = origList.get(i);
13542            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13543                continue;
13544            }
13545            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13546        }
13547
13548        if (list.size() <= 0) {
13549            return false;
13550        }
13551
13552        Comparator<Pair<ProcessRecord, Integer>> comparator
13553                = new Comparator<Pair<ProcessRecord, Integer>>() {
13554            @Override
13555            public int compare(Pair<ProcessRecord, Integer> object1,
13556                    Pair<ProcessRecord, Integer> object2) {
13557                if (object1.first.setAdj != object2.first.setAdj) {
13558                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13559                }
13560                if (object1.second.intValue() != object2.second.intValue()) {
13561                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13562                }
13563                return 0;
13564            }
13565        };
13566
13567        Collections.sort(list, comparator);
13568
13569        final long curRealtime = SystemClock.elapsedRealtime();
13570        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13571        final long curUptime = SystemClock.uptimeMillis();
13572        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13573
13574        for (int i=list.size()-1; i>=0; i--) {
13575            ProcessRecord r = list.get(i).first;
13576            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13577            char schedGroup;
13578            switch (r.setSchedGroup) {
13579                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13580                    schedGroup = 'B';
13581                    break;
13582                case Process.THREAD_GROUP_DEFAULT:
13583                    schedGroup = 'F';
13584                    break;
13585                default:
13586                    schedGroup = '?';
13587                    break;
13588            }
13589            char foreground;
13590            if (r.foregroundActivities) {
13591                foreground = 'A';
13592            } else if (r.foregroundServices) {
13593                foreground = 'S';
13594            } else {
13595                foreground = ' ';
13596            }
13597            String procState = ProcessList.makeProcStateString(r.curProcState);
13598            pw.print(prefix);
13599            pw.print(r.persistent ? persistentLabel : normalLabel);
13600            pw.print(" #");
13601            int num = (origList.size()-1)-list.get(i).second;
13602            if (num < 10) pw.print(' ');
13603            pw.print(num);
13604            pw.print(": ");
13605            pw.print(oomAdj);
13606            pw.print(' ');
13607            pw.print(schedGroup);
13608            pw.print('/');
13609            pw.print(foreground);
13610            pw.print('/');
13611            pw.print(procState);
13612            pw.print(" trm:");
13613            if (r.trimMemoryLevel < 10) pw.print(' ');
13614            pw.print(r.trimMemoryLevel);
13615            pw.print(' ');
13616            pw.print(r.toShortString());
13617            pw.print(" (");
13618            pw.print(r.adjType);
13619            pw.println(')');
13620            if (r.adjSource != null || r.adjTarget != null) {
13621                pw.print(prefix);
13622                pw.print("    ");
13623                if (r.adjTarget instanceof ComponentName) {
13624                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13625                } else if (r.adjTarget != null) {
13626                    pw.print(r.adjTarget.toString());
13627                } else {
13628                    pw.print("{null}");
13629                }
13630                pw.print("<=");
13631                if (r.adjSource instanceof ProcessRecord) {
13632                    pw.print("Proc{");
13633                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13634                    pw.println("}");
13635                } else if (r.adjSource != null) {
13636                    pw.println(r.adjSource.toString());
13637                } else {
13638                    pw.println("{null}");
13639                }
13640            }
13641            if (inclDetails) {
13642                pw.print(prefix);
13643                pw.print("    ");
13644                pw.print("oom: max="); pw.print(r.maxAdj);
13645                pw.print(" curRaw="); pw.print(r.curRawAdj);
13646                pw.print(" setRaw="); pw.print(r.setRawAdj);
13647                pw.print(" cur="); pw.print(r.curAdj);
13648                pw.print(" set="); pw.println(r.setAdj);
13649                pw.print(prefix);
13650                pw.print("    ");
13651                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13652                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13653                pw.print(" lastPss="); pw.print(r.lastPss);
13654                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13655                pw.print(prefix);
13656                pw.print("    ");
13657                pw.print("cached="); pw.print(r.cached);
13658                pw.print(" empty="); pw.print(r.empty);
13659                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13660
13661                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13662                    if (r.lastWakeTime != 0) {
13663                        long wtime;
13664                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13665                        synchronized (stats) {
13666                            wtime = stats.getProcessWakeTime(r.info.uid,
13667                                    r.pid, curRealtime);
13668                        }
13669                        long timeUsed = wtime - r.lastWakeTime;
13670                        pw.print(prefix);
13671                        pw.print("    ");
13672                        pw.print("keep awake over ");
13673                        TimeUtils.formatDuration(realtimeSince, pw);
13674                        pw.print(" used ");
13675                        TimeUtils.formatDuration(timeUsed, pw);
13676                        pw.print(" (");
13677                        pw.print((timeUsed*100)/realtimeSince);
13678                        pw.println("%)");
13679                    }
13680                    if (r.lastCpuTime != 0) {
13681                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13682                        pw.print(prefix);
13683                        pw.print("    ");
13684                        pw.print("run cpu over ");
13685                        TimeUtils.formatDuration(uptimeSince, pw);
13686                        pw.print(" used ");
13687                        TimeUtils.formatDuration(timeUsed, pw);
13688                        pw.print(" (");
13689                        pw.print((timeUsed*100)/uptimeSince);
13690                        pw.println("%)");
13691                    }
13692                }
13693            }
13694        }
13695        return true;
13696    }
13697
13698    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13699            String[] args) {
13700        ArrayList<ProcessRecord> procs;
13701        synchronized (this) {
13702            if (args != null && args.length > start
13703                    && args[start].charAt(0) != '-') {
13704                procs = new ArrayList<ProcessRecord>();
13705                int pid = -1;
13706                try {
13707                    pid = Integer.parseInt(args[start]);
13708                } catch (NumberFormatException e) {
13709                }
13710                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13711                    ProcessRecord proc = mLruProcesses.get(i);
13712                    if (proc.pid == pid) {
13713                        procs.add(proc);
13714                    } else if (allPkgs && proc.pkgList != null
13715                            && proc.pkgList.containsKey(args[start])) {
13716                        procs.add(proc);
13717                    } else if (proc.processName.equals(args[start])) {
13718                        procs.add(proc);
13719                    }
13720                }
13721                if (procs.size() <= 0) {
13722                    return null;
13723                }
13724            } else {
13725                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13726            }
13727        }
13728        return procs;
13729    }
13730
13731    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13732            PrintWriter pw, String[] args) {
13733        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13734        if (procs == null) {
13735            pw.println("No process found for: " + args[0]);
13736            return;
13737        }
13738
13739        long uptime = SystemClock.uptimeMillis();
13740        long realtime = SystemClock.elapsedRealtime();
13741        pw.println("Applications Graphics Acceleration Info:");
13742        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13743
13744        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13745            ProcessRecord r = procs.get(i);
13746            if (r.thread != null) {
13747                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13748                pw.flush();
13749                try {
13750                    TransferPipe tp = new TransferPipe();
13751                    try {
13752                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13753                        tp.go(fd);
13754                    } finally {
13755                        tp.kill();
13756                    }
13757                } catch (IOException e) {
13758                    pw.println("Failure while dumping the app: " + r);
13759                    pw.flush();
13760                } catch (RemoteException e) {
13761                    pw.println("Got a RemoteException while dumping the app " + r);
13762                    pw.flush();
13763                }
13764            }
13765        }
13766    }
13767
13768    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13769        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13770        if (procs == null) {
13771            pw.println("No process found for: " + args[0]);
13772            return;
13773        }
13774
13775        pw.println("Applications Database Info:");
13776
13777        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13778            ProcessRecord r = procs.get(i);
13779            if (r.thread != null) {
13780                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13781                pw.flush();
13782                try {
13783                    TransferPipe tp = new TransferPipe();
13784                    try {
13785                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13786                        tp.go(fd);
13787                    } finally {
13788                        tp.kill();
13789                    }
13790                } catch (IOException e) {
13791                    pw.println("Failure while dumping the app: " + r);
13792                    pw.flush();
13793                } catch (RemoteException e) {
13794                    pw.println("Got a RemoteException while dumping the app " + r);
13795                    pw.flush();
13796                }
13797            }
13798        }
13799    }
13800
13801    final static class MemItem {
13802        final boolean isProc;
13803        final String label;
13804        final String shortLabel;
13805        final long pss;
13806        final int id;
13807        final boolean hasActivities;
13808        ArrayList<MemItem> subitems;
13809
13810        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13811                boolean _hasActivities) {
13812            isProc = true;
13813            label = _label;
13814            shortLabel = _shortLabel;
13815            pss = _pss;
13816            id = _id;
13817            hasActivities = _hasActivities;
13818        }
13819
13820        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13821            isProc = false;
13822            label = _label;
13823            shortLabel = _shortLabel;
13824            pss = _pss;
13825            id = _id;
13826            hasActivities = false;
13827        }
13828    }
13829
13830    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13831            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13832        if (sort && !isCompact) {
13833            Collections.sort(items, new Comparator<MemItem>() {
13834                @Override
13835                public int compare(MemItem lhs, MemItem rhs) {
13836                    if (lhs.pss < rhs.pss) {
13837                        return 1;
13838                    } else if (lhs.pss > rhs.pss) {
13839                        return -1;
13840                    }
13841                    return 0;
13842                }
13843            });
13844        }
13845
13846        for (int i=0; i<items.size(); i++) {
13847            MemItem mi = items.get(i);
13848            if (!isCompact) {
13849                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13850            } else if (mi.isProc) {
13851                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13852                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13853                pw.println(mi.hasActivities ? ",a" : ",e");
13854            } else {
13855                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13856                pw.println(mi.pss);
13857            }
13858            if (mi.subitems != null) {
13859                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13860                        true, isCompact);
13861            }
13862        }
13863    }
13864
13865    // These are in KB.
13866    static final long[] DUMP_MEM_BUCKETS = new long[] {
13867        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13868        120*1024, 160*1024, 200*1024,
13869        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13870        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13871    };
13872
13873    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13874            boolean stackLike) {
13875        int start = label.lastIndexOf('.');
13876        if (start >= 0) start++;
13877        else start = 0;
13878        int end = label.length();
13879        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13880            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13881                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13882                out.append(bucket);
13883                out.append(stackLike ? "MB." : "MB ");
13884                out.append(label, start, end);
13885                return;
13886            }
13887        }
13888        out.append(memKB/1024);
13889        out.append(stackLike ? "MB." : "MB ");
13890        out.append(label, start, end);
13891    }
13892
13893    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13894            ProcessList.NATIVE_ADJ,
13895            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13896            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13897            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13898            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13899            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13900            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13901    };
13902    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13903            "Native",
13904            "System", "Persistent", "Persistent Service", "Foreground",
13905            "Visible", "Perceptible",
13906            "Heavy Weight", "Backup",
13907            "A Services", "Home",
13908            "Previous", "B Services", "Cached"
13909    };
13910    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13911            "native",
13912            "sys", "pers", "persvc", "fore",
13913            "vis", "percept",
13914            "heavy", "backup",
13915            "servicea", "home",
13916            "prev", "serviceb", "cached"
13917    };
13918
13919    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13920            long realtime, boolean isCheckinRequest, boolean isCompact) {
13921        if (isCheckinRequest || isCompact) {
13922            // short checkin version
13923            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13924        } else {
13925            pw.println("Applications Memory Usage (kB):");
13926            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13927        }
13928    }
13929
13930    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13931            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13932        boolean dumpDetails = false;
13933        boolean dumpFullDetails = false;
13934        boolean dumpDalvik = false;
13935        boolean oomOnly = false;
13936        boolean isCompact = false;
13937        boolean localOnly = false;
13938        boolean packages = false;
13939
13940        int opti = 0;
13941        while (opti < args.length) {
13942            String opt = args[opti];
13943            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13944                break;
13945            }
13946            opti++;
13947            if ("-a".equals(opt)) {
13948                dumpDetails = true;
13949                dumpFullDetails = true;
13950                dumpDalvik = true;
13951            } else if ("-d".equals(opt)) {
13952                dumpDalvik = true;
13953            } else if ("-c".equals(opt)) {
13954                isCompact = true;
13955            } else if ("--oom".equals(opt)) {
13956                oomOnly = true;
13957            } else if ("--local".equals(opt)) {
13958                localOnly = true;
13959            } else if ("--package".equals(opt)) {
13960                packages = true;
13961            } else if ("-h".equals(opt)) {
13962                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13963                pw.println("  -a: include all available information for each process.");
13964                pw.println("  -d: include dalvik details when dumping process details.");
13965                pw.println("  -c: dump in a compact machine-parseable representation.");
13966                pw.println("  --oom: only show processes organized by oom adj.");
13967                pw.println("  --local: only collect details locally, don't call process.");
13968                pw.println("  --package: interpret process arg as package, dumping all");
13969                pw.println("             processes that have loaded that package.");
13970                pw.println("If [process] is specified it can be the name or ");
13971                pw.println("pid of a specific process to dump.");
13972                return;
13973            } else {
13974                pw.println("Unknown argument: " + opt + "; use -h for help");
13975            }
13976        }
13977
13978        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13979        long uptime = SystemClock.uptimeMillis();
13980        long realtime = SystemClock.elapsedRealtime();
13981        final long[] tmpLong = new long[1];
13982
13983        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13984        if (procs == null) {
13985            // No Java processes.  Maybe they want to print a native process.
13986            if (args != null && args.length > opti
13987                    && args[opti].charAt(0) != '-') {
13988                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13989                        = new ArrayList<ProcessCpuTracker.Stats>();
13990                updateCpuStatsNow();
13991                int findPid = -1;
13992                try {
13993                    findPid = Integer.parseInt(args[opti]);
13994                } catch (NumberFormatException e) {
13995                }
13996                synchronized (mProcessCpuTracker) {
13997                    final int N = mProcessCpuTracker.countStats();
13998                    for (int i=0; i<N; i++) {
13999                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14000                        if (st.pid == findPid || (st.baseName != null
14001                                && st.baseName.equals(args[opti]))) {
14002                            nativeProcs.add(st);
14003                        }
14004                    }
14005                }
14006                if (nativeProcs.size() > 0) {
14007                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14008                            isCompact);
14009                    Debug.MemoryInfo mi = null;
14010                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14011                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14012                        final int pid = r.pid;
14013                        if (!isCheckinRequest && dumpDetails) {
14014                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14015                        }
14016                        if (mi == null) {
14017                            mi = new Debug.MemoryInfo();
14018                        }
14019                        if (dumpDetails || (!brief && !oomOnly)) {
14020                            Debug.getMemoryInfo(pid, mi);
14021                        } else {
14022                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14023                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14024                        }
14025                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14026                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14027                        if (isCheckinRequest) {
14028                            pw.println();
14029                        }
14030                    }
14031                    return;
14032                }
14033            }
14034            pw.println("No process found for: " + args[opti]);
14035            return;
14036        }
14037
14038        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14039            dumpDetails = true;
14040        }
14041
14042        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14043
14044        String[] innerArgs = new String[args.length-opti];
14045        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14046
14047        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14048        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14049        long nativePss=0, dalvikPss=0, otherPss=0;
14050        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14051
14052        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14053        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14054                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14055
14056        long totalPss = 0;
14057        long cachedPss = 0;
14058
14059        Debug.MemoryInfo mi = null;
14060        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14061            final ProcessRecord r = procs.get(i);
14062            final IApplicationThread thread;
14063            final int pid;
14064            final int oomAdj;
14065            final boolean hasActivities;
14066            synchronized (this) {
14067                thread = r.thread;
14068                pid = r.pid;
14069                oomAdj = r.getSetAdjWithServices();
14070                hasActivities = r.activities.size() > 0;
14071            }
14072            if (thread != null) {
14073                if (!isCheckinRequest && dumpDetails) {
14074                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14075                }
14076                if (mi == null) {
14077                    mi = new Debug.MemoryInfo();
14078                }
14079                if (dumpDetails || (!brief && !oomOnly)) {
14080                    Debug.getMemoryInfo(pid, mi);
14081                } else {
14082                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14083                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14084                }
14085                if (dumpDetails) {
14086                    if (localOnly) {
14087                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14088                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14089                        if (isCheckinRequest) {
14090                            pw.println();
14091                        }
14092                    } else {
14093                        try {
14094                            pw.flush();
14095                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14096                                    dumpDalvik, innerArgs);
14097                        } catch (RemoteException e) {
14098                            if (!isCheckinRequest) {
14099                                pw.println("Got RemoteException!");
14100                                pw.flush();
14101                            }
14102                        }
14103                    }
14104                }
14105
14106                final long myTotalPss = mi.getTotalPss();
14107                final long myTotalUss = mi.getTotalUss();
14108
14109                synchronized (this) {
14110                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14111                        // Record this for posterity if the process has been stable.
14112                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14113                    }
14114                }
14115
14116                if (!isCheckinRequest && mi != null) {
14117                    totalPss += myTotalPss;
14118                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14119                            (hasActivities ? " / activities)" : ")"),
14120                            r.processName, myTotalPss, pid, hasActivities);
14121                    procMems.add(pssItem);
14122                    procMemsMap.put(pid, pssItem);
14123
14124                    nativePss += mi.nativePss;
14125                    dalvikPss += mi.dalvikPss;
14126                    otherPss += mi.otherPss;
14127                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14128                        long mem = mi.getOtherPss(j);
14129                        miscPss[j] += mem;
14130                        otherPss -= mem;
14131                    }
14132
14133                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14134                        cachedPss += myTotalPss;
14135                    }
14136
14137                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14138                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14139                                || oomIndex == (oomPss.length-1)) {
14140                            oomPss[oomIndex] += myTotalPss;
14141                            if (oomProcs[oomIndex] == null) {
14142                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14143                            }
14144                            oomProcs[oomIndex].add(pssItem);
14145                            break;
14146                        }
14147                    }
14148                }
14149            }
14150        }
14151
14152        long nativeProcTotalPss = 0;
14153
14154        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14155            // If we are showing aggregations, also look for native processes to
14156            // include so that our aggregations are more accurate.
14157            updateCpuStatsNow();
14158            synchronized (mProcessCpuTracker) {
14159                final int N = mProcessCpuTracker.countStats();
14160                for (int i=0; i<N; i++) {
14161                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14162                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14163                        if (mi == null) {
14164                            mi = new Debug.MemoryInfo();
14165                        }
14166                        if (!brief && !oomOnly) {
14167                            Debug.getMemoryInfo(st.pid, mi);
14168                        } else {
14169                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14170                            mi.nativePrivateDirty = (int)tmpLong[0];
14171                        }
14172
14173                        final long myTotalPss = mi.getTotalPss();
14174                        totalPss += myTotalPss;
14175                        nativeProcTotalPss += myTotalPss;
14176
14177                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14178                                st.name, myTotalPss, st.pid, false);
14179                        procMems.add(pssItem);
14180
14181                        nativePss += mi.nativePss;
14182                        dalvikPss += mi.dalvikPss;
14183                        otherPss += mi.otherPss;
14184                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14185                            long mem = mi.getOtherPss(j);
14186                            miscPss[j] += mem;
14187                            otherPss -= mem;
14188                        }
14189                        oomPss[0] += myTotalPss;
14190                        if (oomProcs[0] == null) {
14191                            oomProcs[0] = new ArrayList<MemItem>();
14192                        }
14193                        oomProcs[0].add(pssItem);
14194                    }
14195                }
14196            }
14197
14198            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14199
14200            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14201            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14202            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14203            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14204                String label = Debug.MemoryInfo.getOtherLabel(j);
14205                catMems.add(new MemItem(label, label, miscPss[j], j));
14206            }
14207
14208            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14209            for (int j=0; j<oomPss.length; j++) {
14210                if (oomPss[j] != 0) {
14211                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14212                            : DUMP_MEM_OOM_LABEL[j];
14213                    MemItem item = new MemItem(label, label, oomPss[j],
14214                            DUMP_MEM_OOM_ADJ[j]);
14215                    item.subitems = oomProcs[j];
14216                    oomMems.add(item);
14217                }
14218            }
14219
14220            if (!brief && !oomOnly && !isCompact) {
14221                pw.println();
14222                pw.println("Total PSS by process:");
14223                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14224                pw.println();
14225            }
14226            if (!isCompact) {
14227                pw.println("Total PSS by OOM adjustment:");
14228            }
14229            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14230            if (!brief && !oomOnly) {
14231                PrintWriter out = categoryPw != null ? categoryPw : pw;
14232                if (!isCompact) {
14233                    out.println();
14234                    out.println("Total PSS by category:");
14235                }
14236                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14237            }
14238            if (!isCompact) {
14239                pw.println();
14240            }
14241            MemInfoReader memInfo = new MemInfoReader();
14242            memInfo.readMemInfo();
14243            if (nativeProcTotalPss > 0) {
14244                synchronized (this) {
14245                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14246                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14247                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14248                }
14249            }
14250            if (!brief) {
14251                if (!isCompact) {
14252                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14253                    pw.print(" kB (status ");
14254                    switch (mLastMemoryLevel) {
14255                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14256                            pw.println("normal)");
14257                            break;
14258                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14259                            pw.println("moderate)");
14260                            break;
14261                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14262                            pw.println("low)");
14263                            break;
14264                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14265                            pw.println("critical)");
14266                            break;
14267                        default:
14268                            pw.print(mLastMemoryLevel);
14269                            pw.println(")");
14270                            break;
14271                    }
14272                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14273                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14274                            pw.print(cachedPss); pw.print(" cached pss + ");
14275                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14276                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14277                } else {
14278                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14279                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14280                            + memInfo.getFreeSizeKb()); pw.print(",");
14281                    pw.println(totalPss - cachedPss);
14282                }
14283            }
14284            if (!isCompact) {
14285                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14286                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14287                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14288                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14289                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14290                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14291                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14292            }
14293            if (!brief) {
14294                if (memInfo.getZramTotalSizeKb() != 0) {
14295                    if (!isCompact) {
14296                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14297                                pw.print(" kB physical used for ");
14298                                pw.print(memInfo.getSwapTotalSizeKb()
14299                                        - memInfo.getSwapFreeSizeKb());
14300                                pw.print(" kB in swap (");
14301                                pw.print(memInfo.getSwapTotalSizeKb());
14302                                pw.println(" kB total swap)");
14303                    } else {
14304                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14305                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14306                                pw.println(memInfo.getSwapFreeSizeKb());
14307                    }
14308                }
14309                final int[] SINGLE_LONG_FORMAT = new int[] {
14310                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14311                };
14312                long[] longOut = new long[1];
14313                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14314                        SINGLE_LONG_FORMAT, null, longOut, null);
14315                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14316                longOut[0] = 0;
14317                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14318                        SINGLE_LONG_FORMAT, null, longOut, null);
14319                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14320                longOut[0] = 0;
14321                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14322                        SINGLE_LONG_FORMAT, null, longOut, null);
14323                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14324                longOut[0] = 0;
14325                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14326                        SINGLE_LONG_FORMAT, null, longOut, null);
14327                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14328                if (!isCompact) {
14329                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14330                        pw.print("      KSM: "); pw.print(sharing);
14331                                pw.print(" kB saved from shared ");
14332                                pw.print(shared); pw.println(" kB");
14333                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14334                                pw.print(voltile); pw.println(" kB volatile");
14335                    }
14336                    pw.print("   Tuning: ");
14337                    pw.print(ActivityManager.staticGetMemoryClass());
14338                    pw.print(" (large ");
14339                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14340                    pw.print("), oom ");
14341                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14342                    pw.print(" kB");
14343                    pw.print(", restore limit ");
14344                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14345                    pw.print(" kB");
14346                    if (ActivityManager.isLowRamDeviceStatic()) {
14347                        pw.print(" (low-ram)");
14348                    }
14349                    if (ActivityManager.isHighEndGfx()) {
14350                        pw.print(" (high-end-gfx)");
14351                    }
14352                    pw.println();
14353                } else {
14354                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14355                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14356                    pw.println(voltile);
14357                    pw.print("tuning,");
14358                    pw.print(ActivityManager.staticGetMemoryClass());
14359                    pw.print(',');
14360                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14361                    pw.print(',');
14362                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14363                    if (ActivityManager.isLowRamDeviceStatic()) {
14364                        pw.print(",low-ram");
14365                    }
14366                    if (ActivityManager.isHighEndGfx()) {
14367                        pw.print(",high-end-gfx");
14368                    }
14369                    pw.println();
14370                }
14371            }
14372        }
14373    }
14374
14375    /**
14376     * Searches array of arguments for the specified string
14377     * @param args array of argument strings
14378     * @param value value to search for
14379     * @return true if the value is contained in the array
14380     */
14381    private static boolean scanArgs(String[] args, String value) {
14382        if (args != null) {
14383            for (String arg : args) {
14384                if (value.equals(arg)) {
14385                    return true;
14386                }
14387            }
14388        }
14389        return false;
14390    }
14391
14392    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14393            ContentProviderRecord cpr, boolean always) {
14394        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14395
14396        if (!inLaunching || always) {
14397            synchronized (cpr) {
14398                cpr.launchingApp = null;
14399                cpr.notifyAll();
14400            }
14401            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14402            String names[] = cpr.info.authority.split(";");
14403            for (int j = 0; j < names.length; j++) {
14404                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14405            }
14406        }
14407
14408        for (int i=0; i<cpr.connections.size(); i++) {
14409            ContentProviderConnection conn = cpr.connections.get(i);
14410            if (conn.waiting) {
14411                // If this connection is waiting for the provider, then we don't
14412                // need to mess with its process unless we are always removing
14413                // or for some reason the provider is not currently launching.
14414                if (inLaunching && !always) {
14415                    continue;
14416                }
14417            }
14418            ProcessRecord capp = conn.client;
14419            conn.dead = true;
14420            if (conn.stableCount > 0) {
14421                if (!capp.persistent && capp.thread != null
14422                        && capp.pid != 0
14423                        && capp.pid != MY_PID) {
14424                    capp.kill("depends on provider "
14425                            + cpr.name.flattenToShortString()
14426                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14427                }
14428            } else if (capp.thread != null && conn.provider.provider != null) {
14429                try {
14430                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14431                } catch (RemoteException e) {
14432                }
14433                // In the protocol here, we don't expect the client to correctly
14434                // clean up this connection, we'll just remove it.
14435                cpr.connections.remove(i);
14436                conn.client.conProviders.remove(conn);
14437            }
14438        }
14439
14440        if (inLaunching && always) {
14441            mLaunchingProviders.remove(cpr);
14442        }
14443        return inLaunching;
14444    }
14445
14446    /**
14447     * Main code for cleaning up a process when it has gone away.  This is
14448     * called both as a result of the process dying, or directly when stopping
14449     * a process when running in single process mode.
14450     *
14451     * @return Returns true if the given process has been restarted, so the
14452     * app that was passed in must remain on the process lists.
14453     */
14454    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14455            boolean restarting, boolean allowRestart, int index) {
14456        if (index >= 0) {
14457            removeLruProcessLocked(app);
14458            ProcessList.remove(app.pid);
14459        }
14460
14461        mProcessesToGc.remove(app);
14462        mPendingPssProcesses.remove(app);
14463
14464        // Dismiss any open dialogs.
14465        if (app.crashDialog != null && !app.forceCrashReport) {
14466            app.crashDialog.dismiss();
14467            app.crashDialog = null;
14468        }
14469        if (app.anrDialog != null) {
14470            app.anrDialog.dismiss();
14471            app.anrDialog = null;
14472        }
14473        if (app.waitDialog != null) {
14474            app.waitDialog.dismiss();
14475            app.waitDialog = null;
14476        }
14477
14478        app.crashing = false;
14479        app.notResponding = false;
14480
14481        app.resetPackageList(mProcessStats);
14482        app.unlinkDeathRecipient();
14483        app.makeInactive(mProcessStats);
14484        app.waitingToKill = null;
14485        app.forcingToForeground = null;
14486        updateProcessForegroundLocked(app, false, false);
14487        app.foregroundActivities = false;
14488        app.hasShownUi = false;
14489        app.treatLikeActivity = false;
14490        app.hasAboveClient = false;
14491        app.hasClientActivities = false;
14492
14493        mServices.killServicesLocked(app, allowRestart);
14494
14495        boolean restart = false;
14496
14497        // Remove published content providers.
14498        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14499            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14500            final boolean always = app.bad || !allowRestart;
14501            if (removeDyingProviderLocked(app, cpr, always) || always) {
14502                // We left the provider in the launching list, need to
14503                // restart it.
14504                restart = true;
14505            }
14506
14507            cpr.provider = null;
14508            cpr.proc = null;
14509        }
14510        app.pubProviders.clear();
14511
14512        // Take care of any launching providers waiting for this process.
14513        if (checkAppInLaunchingProvidersLocked(app, false)) {
14514            restart = true;
14515        }
14516
14517        // Unregister from connected content providers.
14518        if (!app.conProviders.isEmpty()) {
14519            for (int i=0; i<app.conProviders.size(); i++) {
14520                ContentProviderConnection conn = app.conProviders.get(i);
14521                conn.provider.connections.remove(conn);
14522            }
14523            app.conProviders.clear();
14524        }
14525
14526        // At this point there may be remaining entries in mLaunchingProviders
14527        // where we were the only one waiting, so they are no longer of use.
14528        // Look for these and clean up if found.
14529        // XXX Commented out for now.  Trying to figure out a way to reproduce
14530        // the actual situation to identify what is actually going on.
14531        if (false) {
14532            for (int i=0; i<mLaunchingProviders.size(); i++) {
14533                ContentProviderRecord cpr = (ContentProviderRecord)
14534                        mLaunchingProviders.get(i);
14535                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14536                    synchronized (cpr) {
14537                        cpr.launchingApp = null;
14538                        cpr.notifyAll();
14539                    }
14540                }
14541            }
14542        }
14543
14544        skipCurrentReceiverLocked(app);
14545
14546        // Unregister any receivers.
14547        for (int i=app.receivers.size()-1; i>=0; i--) {
14548            removeReceiverLocked(app.receivers.valueAt(i));
14549        }
14550        app.receivers.clear();
14551
14552        // If the app is undergoing backup, tell the backup manager about it
14553        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14554            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14555                    + mBackupTarget.appInfo + " died during backup");
14556            try {
14557                IBackupManager bm = IBackupManager.Stub.asInterface(
14558                        ServiceManager.getService(Context.BACKUP_SERVICE));
14559                bm.agentDisconnected(app.info.packageName);
14560            } catch (RemoteException e) {
14561                // can't happen; backup manager is local
14562            }
14563        }
14564
14565        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14566            ProcessChangeItem item = mPendingProcessChanges.get(i);
14567            if (item.pid == app.pid) {
14568                mPendingProcessChanges.remove(i);
14569                mAvailProcessChanges.add(item);
14570            }
14571        }
14572        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14573
14574        // If the caller is restarting this app, then leave it in its
14575        // current lists and let the caller take care of it.
14576        if (restarting) {
14577            return false;
14578        }
14579
14580        if (!app.persistent || app.isolated) {
14581            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14582                    "Removing non-persistent process during cleanup: " + app);
14583            mProcessNames.remove(app.processName, app.uid);
14584            mIsolatedProcesses.remove(app.uid);
14585            if (mHeavyWeightProcess == app) {
14586                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14587                        mHeavyWeightProcess.userId, 0));
14588                mHeavyWeightProcess = null;
14589            }
14590        } else if (!app.removed) {
14591            // This app is persistent, so we need to keep its record around.
14592            // If it is not already on the pending app list, add it there
14593            // and start a new process for it.
14594            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14595                mPersistentStartingProcesses.add(app);
14596                restart = true;
14597            }
14598        }
14599        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14600                "Clean-up removing on hold: " + app);
14601        mProcessesOnHold.remove(app);
14602
14603        if (app == mHomeProcess) {
14604            mHomeProcess = null;
14605        }
14606        if (app == mPreviousProcess) {
14607            mPreviousProcess = null;
14608        }
14609
14610        if (restart && !app.isolated) {
14611            // We have components that still need to be running in the
14612            // process, so re-launch it.
14613            if (index < 0) {
14614                ProcessList.remove(app.pid);
14615            }
14616            mProcessNames.put(app.processName, app.uid, app);
14617            startProcessLocked(app, "restart", app.processName);
14618            return true;
14619        } else if (app.pid > 0 && app.pid != MY_PID) {
14620            // Goodbye!
14621            boolean removed;
14622            synchronized (mPidsSelfLocked) {
14623                mPidsSelfLocked.remove(app.pid);
14624                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14625            }
14626            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14627            if (app.isolated) {
14628                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14629            }
14630            app.setPid(0);
14631        }
14632        return false;
14633    }
14634
14635    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14636        // Look through the content providers we are waiting to have launched,
14637        // and if any run in this process then either schedule a restart of
14638        // the process or kill the client waiting for it if this process has
14639        // gone bad.
14640        int NL = mLaunchingProviders.size();
14641        boolean restart = false;
14642        for (int i=0; i<NL; i++) {
14643            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14644            if (cpr.launchingApp == app) {
14645                if (!alwaysBad && !app.bad) {
14646                    restart = true;
14647                } else {
14648                    removeDyingProviderLocked(app, cpr, true);
14649                    // cpr should have been removed from mLaunchingProviders
14650                    NL = mLaunchingProviders.size();
14651                    i--;
14652                }
14653            }
14654        }
14655        return restart;
14656    }
14657
14658    // =========================================================
14659    // SERVICES
14660    // =========================================================
14661
14662    @Override
14663    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14664            int flags) {
14665        enforceNotIsolatedCaller("getServices");
14666        synchronized (this) {
14667            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14668        }
14669    }
14670
14671    @Override
14672    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14673        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14674        synchronized (this) {
14675            return mServices.getRunningServiceControlPanelLocked(name);
14676        }
14677    }
14678
14679    @Override
14680    public ComponentName startService(IApplicationThread caller, Intent service,
14681            String resolvedType, int userId) {
14682        enforceNotIsolatedCaller("startService");
14683        // Refuse possible leaked file descriptors
14684        if (service != null && service.hasFileDescriptors() == true) {
14685            throw new IllegalArgumentException("File descriptors passed in Intent");
14686        }
14687
14688        if (DEBUG_SERVICE)
14689            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14690        synchronized(this) {
14691            final int callingPid = Binder.getCallingPid();
14692            final int callingUid = Binder.getCallingUid();
14693            final long origId = Binder.clearCallingIdentity();
14694            ComponentName res = mServices.startServiceLocked(caller, service,
14695                    resolvedType, callingPid, callingUid, userId);
14696            Binder.restoreCallingIdentity(origId);
14697            return res;
14698        }
14699    }
14700
14701    ComponentName startServiceInPackage(int uid,
14702            Intent service, String resolvedType, int userId) {
14703        synchronized(this) {
14704            if (DEBUG_SERVICE)
14705                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14706            final long origId = Binder.clearCallingIdentity();
14707            ComponentName res = mServices.startServiceLocked(null, service,
14708                    resolvedType, -1, uid, userId);
14709            Binder.restoreCallingIdentity(origId);
14710            return res;
14711        }
14712    }
14713
14714    @Override
14715    public int stopService(IApplicationThread caller, Intent service,
14716            String resolvedType, int userId) {
14717        enforceNotIsolatedCaller("stopService");
14718        // Refuse possible leaked file descriptors
14719        if (service != null && service.hasFileDescriptors() == true) {
14720            throw new IllegalArgumentException("File descriptors passed in Intent");
14721        }
14722
14723        synchronized(this) {
14724            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14725        }
14726    }
14727
14728    @Override
14729    public IBinder peekService(Intent service, String resolvedType) {
14730        enforceNotIsolatedCaller("peekService");
14731        // Refuse possible leaked file descriptors
14732        if (service != null && service.hasFileDescriptors() == true) {
14733            throw new IllegalArgumentException("File descriptors passed in Intent");
14734        }
14735        synchronized(this) {
14736            return mServices.peekServiceLocked(service, resolvedType);
14737        }
14738    }
14739
14740    @Override
14741    public boolean stopServiceToken(ComponentName className, IBinder token,
14742            int startId) {
14743        synchronized(this) {
14744            return mServices.stopServiceTokenLocked(className, token, startId);
14745        }
14746    }
14747
14748    @Override
14749    public void setServiceForeground(ComponentName className, IBinder token,
14750            int id, Notification notification, boolean removeNotification) {
14751        synchronized(this) {
14752            mServices.setServiceForegroundLocked(className, token, id, notification,
14753                    removeNotification);
14754        }
14755    }
14756
14757    @Override
14758    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14759            boolean requireFull, String name, String callerPackage) {
14760        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14761                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14762    }
14763
14764    int unsafeConvertIncomingUser(int userId) {
14765        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14766                ? mCurrentUserId : userId;
14767    }
14768
14769    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14770            int allowMode, String name, String callerPackage) {
14771        final int callingUserId = UserHandle.getUserId(callingUid);
14772        if (callingUserId == userId) {
14773            return userId;
14774        }
14775
14776        // Note that we may be accessing mCurrentUserId outside of a lock...
14777        // shouldn't be a big deal, if this is being called outside
14778        // of a locked context there is intrinsically a race with
14779        // the value the caller will receive and someone else changing it.
14780        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14781        // we will switch to the calling user if access to the current user fails.
14782        int targetUserId = unsafeConvertIncomingUser(userId);
14783
14784        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14785            final boolean allow;
14786            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14787                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14788                // If the caller has this permission, they always pass go.  And collect $200.
14789                allow = true;
14790            } else if (allowMode == ALLOW_FULL_ONLY) {
14791                // We require full access, sucks to be you.
14792                allow = false;
14793            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14794                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14795                // If the caller does not have either permission, they are always doomed.
14796                allow = false;
14797            } else if (allowMode == ALLOW_NON_FULL) {
14798                // We are blanket allowing non-full access, you lucky caller!
14799                allow = true;
14800            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14801                // We may or may not allow this depending on whether the two users are
14802                // in the same profile.
14803                synchronized (mUserProfileGroupIdsSelfLocked) {
14804                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14805                            UserInfo.NO_PROFILE_GROUP_ID);
14806                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14807                            UserInfo.NO_PROFILE_GROUP_ID);
14808                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14809                            && callingProfile == targetProfile;
14810                }
14811            } else {
14812                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14813            }
14814            if (!allow) {
14815                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14816                    // In this case, they would like to just execute as their
14817                    // owner user instead of failing.
14818                    targetUserId = callingUserId;
14819                } else {
14820                    StringBuilder builder = new StringBuilder(128);
14821                    builder.append("Permission Denial: ");
14822                    builder.append(name);
14823                    if (callerPackage != null) {
14824                        builder.append(" from ");
14825                        builder.append(callerPackage);
14826                    }
14827                    builder.append(" asks to run as user ");
14828                    builder.append(userId);
14829                    builder.append(" but is calling from user ");
14830                    builder.append(UserHandle.getUserId(callingUid));
14831                    builder.append("; this requires ");
14832                    builder.append(INTERACT_ACROSS_USERS_FULL);
14833                    if (allowMode != ALLOW_FULL_ONLY) {
14834                        builder.append(" or ");
14835                        builder.append(INTERACT_ACROSS_USERS);
14836                    }
14837                    String msg = builder.toString();
14838                    Slog.w(TAG, msg);
14839                    throw new SecurityException(msg);
14840                }
14841            }
14842        }
14843        if (!allowAll && targetUserId < 0) {
14844            throw new IllegalArgumentException(
14845                    "Call does not support special user #" + targetUserId);
14846        }
14847        // Check shell permission
14848        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14849            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14850                    targetUserId)) {
14851                throw new SecurityException("Shell does not have permission to access user "
14852                        + targetUserId + "\n " + Debug.getCallers(3));
14853            }
14854        }
14855        return targetUserId;
14856    }
14857
14858    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14859            String className, int flags) {
14860        boolean result = false;
14861        // For apps that don't have pre-defined UIDs, check for permission
14862        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14863            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14864                if (ActivityManager.checkUidPermission(
14865                        INTERACT_ACROSS_USERS,
14866                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14867                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14868                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14869                            + " requests FLAG_SINGLE_USER, but app does not hold "
14870                            + INTERACT_ACROSS_USERS;
14871                    Slog.w(TAG, msg);
14872                    throw new SecurityException(msg);
14873                }
14874                // Permission passed
14875                result = true;
14876            }
14877        } else if ("system".equals(componentProcessName)) {
14878            result = true;
14879        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14880            // Phone app and persistent apps are allowed to export singleuser providers.
14881            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14882                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14883        }
14884        if (DEBUG_MU) {
14885            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14886                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14887        }
14888        return result;
14889    }
14890
14891    /**
14892     * Checks to see if the caller is in the same app as the singleton
14893     * component, or the component is in a special app. It allows special apps
14894     * to export singleton components but prevents exporting singleton
14895     * components for regular apps.
14896     */
14897    boolean isValidSingletonCall(int callingUid, int componentUid) {
14898        int componentAppId = UserHandle.getAppId(componentUid);
14899        return UserHandle.isSameApp(callingUid, componentUid)
14900                || componentAppId == Process.SYSTEM_UID
14901                || componentAppId == Process.PHONE_UID
14902                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14903                        == PackageManager.PERMISSION_GRANTED;
14904    }
14905
14906    public int bindService(IApplicationThread caller, IBinder token,
14907            Intent service, String resolvedType,
14908            IServiceConnection connection, int flags, int userId) {
14909        enforceNotIsolatedCaller("bindService");
14910
14911        // Refuse possible leaked file descriptors
14912        if (service != null && service.hasFileDescriptors() == true) {
14913            throw new IllegalArgumentException("File descriptors passed in Intent");
14914        }
14915
14916        synchronized(this) {
14917            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14918                    connection, flags, userId);
14919        }
14920    }
14921
14922    public boolean unbindService(IServiceConnection connection) {
14923        synchronized (this) {
14924            return mServices.unbindServiceLocked(connection);
14925        }
14926    }
14927
14928    public void publishService(IBinder token, Intent intent, IBinder service) {
14929        // Refuse possible leaked file descriptors
14930        if (intent != null && intent.hasFileDescriptors() == true) {
14931            throw new IllegalArgumentException("File descriptors passed in Intent");
14932        }
14933
14934        synchronized(this) {
14935            if (!(token instanceof ServiceRecord)) {
14936                throw new IllegalArgumentException("Invalid service token");
14937            }
14938            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14939        }
14940    }
14941
14942    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14943        // Refuse possible leaked file descriptors
14944        if (intent != null && intent.hasFileDescriptors() == true) {
14945            throw new IllegalArgumentException("File descriptors passed in Intent");
14946        }
14947
14948        synchronized(this) {
14949            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14950        }
14951    }
14952
14953    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14954        synchronized(this) {
14955            if (!(token instanceof ServiceRecord)) {
14956                throw new IllegalArgumentException("Invalid service token");
14957            }
14958            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14959        }
14960    }
14961
14962    // =========================================================
14963    // BACKUP AND RESTORE
14964    // =========================================================
14965
14966    // Cause the target app to be launched if necessary and its backup agent
14967    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14968    // activity manager to announce its creation.
14969    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14970        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14971        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14972
14973        synchronized(this) {
14974            // !!! TODO: currently no check here that we're already bound
14975            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14976            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14977            synchronized (stats) {
14978                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14979            }
14980
14981            // Backup agent is now in use, its package can't be stopped.
14982            try {
14983                AppGlobals.getPackageManager().setPackageStoppedState(
14984                        app.packageName, false, UserHandle.getUserId(app.uid));
14985            } catch (RemoteException e) {
14986            } catch (IllegalArgumentException e) {
14987                Slog.w(TAG, "Failed trying to unstop package "
14988                        + app.packageName + ": " + e);
14989            }
14990
14991            BackupRecord r = new BackupRecord(ss, app, backupMode);
14992            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14993                    ? new ComponentName(app.packageName, app.backupAgentName)
14994                    : new ComponentName("android", "FullBackupAgent");
14995            // startProcessLocked() returns existing proc's record if it's already running
14996            ProcessRecord proc = startProcessLocked(app.processName, app,
14997                    false, 0, "backup", hostingName, false, false, false);
14998            if (proc == null) {
14999                Slog.e(TAG, "Unable to start backup agent process " + r);
15000                return false;
15001            }
15002
15003            r.app = proc;
15004            mBackupTarget = r;
15005            mBackupAppName = app.packageName;
15006
15007            // Try not to kill the process during backup
15008            updateOomAdjLocked(proc);
15009
15010            // If the process is already attached, schedule the creation of the backup agent now.
15011            // If it is not yet live, this will be done when it attaches to the framework.
15012            if (proc.thread != null) {
15013                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15014                try {
15015                    proc.thread.scheduleCreateBackupAgent(app,
15016                            compatibilityInfoForPackageLocked(app), backupMode);
15017                } catch (RemoteException e) {
15018                    // Will time out on the backup manager side
15019                }
15020            } else {
15021                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15022            }
15023            // Invariants: at this point, the target app process exists and the application
15024            // is either already running or in the process of coming up.  mBackupTarget and
15025            // mBackupAppName describe the app, so that when it binds back to the AM we
15026            // know that it's scheduled for a backup-agent operation.
15027        }
15028
15029        return true;
15030    }
15031
15032    @Override
15033    public void clearPendingBackup() {
15034        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15035        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15036
15037        synchronized (this) {
15038            mBackupTarget = null;
15039            mBackupAppName = null;
15040        }
15041    }
15042
15043    // A backup agent has just come up
15044    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15045        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15046                + " = " + agent);
15047
15048        synchronized(this) {
15049            if (!agentPackageName.equals(mBackupAppName)) {
15050                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15051                return;
15052            }
15053        }
15054
15055        long oldIdent = Binder.clearCallingIdentity();
15056        try {
15057            IBackupManager bm = IBackupManager.Stub.asInterface(
15058                    ServiceManager.getService(Context.BACKUP_SERVICE));
15059            bm.agentConnected(agentPackageName, agent);
15060        } catch (RemoteException e) {
15061            // can't happen; the backup manager service is local
15062        } catch (Exception e) {
15063            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15064            e.printStackTrace();
15065        } finally {
15066            Binder.restoreCallingIdentity(oldIdent);
15067        }
15068    }
15069
15070    // done with this agent
15071    public void unbindBackupAgent(ApplicationInfo appInfo) {
15072        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15073        if (appInfo == null) {
15074            Slog.w(TAG, "unbind backup agent for null app");
15075            return;
15076        }
15077
15078        synchronized(this) {
15079            try {
15080                if (mBackupAppName == null) {
15081                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15082                    return;
15083                }
15084
15085                if (!mBackupAppName.equals(appInfo.packageName)) {
15086                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15087                    return;
15088                }
15089
15090                // Not backing this app up any more; reset its OOM adjustment
15091                final ProcessRecord proc = mBackupTarget.app;
15092                updateOomAdjLocked(proc);
15093
15094                // If the app crashed during backup, 'thread' will be null here
15095                if (proc.thread != null) {
15096                    try {
15097                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15098                                compatibilityInfoForPackageLocked(appInfo));
15099                    } catch (Exception e) {
15100                        Slog.e(TAG, "Exception when unbinding backup agent:");
15101                        e.printStackTrace();
15102                    }
15103                }
15104            } finally {
15105                mBackupTarget = null;
15106                mBackupAppName = null;
15107            }
15108        }
15109    }
15110    // =========================================================
15111    // BROADCASTS
15112    // =========================================================
15113
15114    private final List getStickiesLocked(String action, IntentFilter filter,
15115            List cur, int userId) {
15116        final ContentResolver resolver = mContext.getContentResolver();
15117        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15118        if (stickies == null) {
15119            return cur;
15120        }
15121        final ArrayList<Intent> list = stickies.get(action);
15122        if (list == null) {
15123            return cur;
15124        }
15125        int N = list.size();
15126        for (int i=0; i<N; i++) {
15127            Intent intent = list.get(i);
15128            if (filter.match(resolver, intent, true, TAG) >= 0) {
15129                if (cur == null) {
15130                    cur = new ArrayList<Intent>();
15131                }
15132                cur.add(intent);
15133            }
15134        }
15135        return cur;
15136    }
15137
15138    boolean isPendingBroadcastProcessLocked(int pid) {
15139        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15140                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15141    }
15142
15143    void skipPendingBroadcastLocked(int pid) {
15144            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15145            for (BroadcastQueue queue : mBroadcastQueues) {
15146                queue.skipPendingBroadcastLocked(pid);
15147            }
15148    }
15149
15150    // The app just attached; send any pending broadcasts that it should receive
15151    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15152        boolean didSomething = false;
15153        for (BroadcastQueue queue : mBroadcastQueues) {
15154            didSomething |= queue.sendPendingBroadcastsLocked(app);
15155        }
15156        return didSomething;
15157    }
15158
15159    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15160            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15161        enforceNotIsolatedCaller("registerReceiver");
15162        int callingUid;
15163        int callingPid;
15164        synchronized(this) {
15165            ProcessRecord callerApp = null;
15166            if (caller != null) {
15167                callerApp = getRecordForAppLocked(caller);
15168                if (callerApp == null) {
15169                    throw new SecurityException(
15170                            "Unable to find app for caller " + caller
15171                            + " (pid=" + Binder.getCallingPid()
15172                            + ") when registering receiver " + receiver);
15173                }
15174                if (callerApp.info.uid != Process.SYSTEM_UID &&
15175                        !callerApp.pkgList.containsKey(callerPackage) &&
15176                        !"android".equals(callerPackage)) {
15177                    throw new SecurityException("Given caller package " + callerPackage
15178                            + " is not running in process " + callerApp);
15179                }
15180                callingUid = callerApp.info.uid;
15181                callingPid = callerApp.pid;
15182            } else {
15183                callerPackage = null;
15184                callingUid = Binder.getCallingUid();
15185                callingPid = Binder.getCallingPid();
15186            }
15187
15188            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15189                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15190
15191            List allSticky = null;
15192
15193            // Look for any matching sticky broadcasts...
15194            Iterator actions = filter.actionsIterator();
15195            if (actions != null) {
15196                while (actions.hasNext()) {
15197                    String action = (String)actions.next();
15198                    allSticky = getStickiesLocked(action, filter, allSticky,
15199                            UserHandle.USER_ALL);
15200                    allSticky = getStickiesLocked(action, filter, allSticky,
15201                            UserHandle.getUserId(callingUid));
15202                }
15203            } else {
15204                allSticky = getStickiesLocked(null, filter, allSticky,
15205                        UserHandle.USER_ALL);
15206                allSticky = getStickiesLocked(null, filter, allSticky,
15207                        UserHandle.getUserId(callingUid));
15208            }
15209
15210            // The first sticky in the list is returned directly back to
15211            // the client.
15212            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15213
15214            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15215                    + ": " + sticky);
15216
15217            if (receiver == null) {
15218                return sticky;
15219            }
15220
15221            ReceiverList rl
15222                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15223            if (rl == null) {
15224                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15225                        userId, receiver);
15226                if (rl.app != null) {
15227                    rl.app.receivers.add(rl);
15228                } else {
15229                    try {
15230                        receiver.asBinder().linkToDeath(rl, 0);
15231                    } catch (RemoteException e) {
15232                        return sticky;
15233                    }
15234                    rl.linkedToDeath = true;
15235                }
15236                mRegisteredReceivers.put(receiver.asBinder(), rl);
15237            } else if (rl.uid != callingUid) {
15238                throw new IllegalArgumentException(
15239                        "Receiver requested to register for uid " + callingUid
15240                        + " was previously registered for uid " + rl.uid);
15241            } else if (rl.pid != callingPid) {
15242                throw new IllegalArgumentException(
15243                        "Receiver requested to register for pid " + callingPid
15244                        + " was previously registered for pid " + rl.pid);
15245            } else if (rl.userId != userId) {
15246                throw new IllegalArgumentException(
15247                        "Receiver requested to register for user " + userId
15248                        + " was previously registered for user " + rl.userId);
15249            }
15250            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15251                    permission, callingUid, userId);
15252            rl.add(bf);
15253            if (!bf.debugCheck()) {
15254                Slog.w(TAG, "==> For Dynamic broadast");
15255            }
15256            mReceiverResolver.addFilter(bf);
15257
15258            // Enqueue broadcasts for all existing stickies that match
15259            // this filter.
15260            if (allSticky != null) {
15261                ArrayList receivers = new ArrayList();
15262                receivers.add(bf);
15263
15264                int N = allSticky.size();
15265                for (int i=0; i<N; i++) {
15266                    Intent intent = (Intent)allSticky.get(i);
15267                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15268                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15269                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15270                            null, null, false, true, true, -1);
15271                    queue.enqueueParallelBroadcastLocked(r);
15272                    queue.scheduleBroadcastsLocked();
15273                }
15274            }
15275
15276            return sticky;
15277        }
15278    }
15279
15280    public void unregisterReceiver(IIntentReceiver receiver) {
15281        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15282
15283        final long origId = Binder.clearCallingIdentity();
15284        try {
15285            boolean doTrim = false;
15286
15287            synchronized(this) {
15288                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15289                if (rl != null) {
15290                    if (rl.curBroadcast != null) {
15291                        BroadcastRecord r = rl.curBroadcast;
15292                        final boolean doNext = finishReceiverLocked(
15293                                receiver.asBinder(), r.resultCode, r.resultData,
15294                                r.resultExtras, r.resultAbort);
15295                        if (doNext) {
15296                            doTrim = true;
15297                            r.queue.processNextBroadcast(false);
15298                        }
15299                    }
15300
15301                    if (rl.app != null) {
15302                        rl.app.receivers.remove(rl);
15303                    }
15304                    removeReceiverLocked(rl);
15305                    if (rl.linkedToDeath) {
15306                        rl.linkedToDeath = false;
15307                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15308                    }
15309                }
15310            }
15311
15312            // If we actually concluded any broadcasts, we might now be able
15313            // to trim the recipients' apps from our working set
15314            if (doTrim) {
15315                trimApplications();
15316                return;
15317            }
15318
15319        } finally {
15320            Binder.restoreCallingIdentity(origId);
15321        }
15322    }
15323
15324    void removeReceiverLocked(ReceiverList rl) {
15325        mRegisteredReceivers.remove(rl.receiver.asBinder());
15326        int N = rl.size();
15327        for (int i=0; i<N; i++) {
15328            mReceiverResolver.removeFilter(rl.get(i));
15329        }
15330    }
15331
15332    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15333        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15334            ProcessRecord r = mLruProcesses.get(i);
15335            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15336                try {
15337                    r.thread.dispatchPackageBroadcast(cmd, packages);
15338                } catch (RemoteException ex) {
15339                }
15340            }
15341        }
15342    }
15343
15344    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15345            int callingUid, int[] users) {
15346        List<ResolveInfo> receivers = null;
15347        try {
15348            HashSet<ComponentName> singleUserReceivers = null;
15349            boolean scannedFirstReceivers = false;
15350            for (int user : users) {
15351                // Skip users that have Shell restrictions
15352                if (callingUid == Process.SHELL_UID
15353                        && getUserManagerLocked().hasUserRestriction(
15354                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15355                    continue;
15356                }
15357                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15358                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15359                if (user != 0 && newReceivers != null) {
15360                    // If this is not the primary user, we need to check for
15361                    // any receivers that should be filtered out.
15362                    for (int i=0; i<newReceivers.size(); i++) {
15363                        ResolveInfo ri = newReceivers.get(i);
15364                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15365                            newReceivers.remove(i);
15366                            i--;
15367                        }
15368                    }
15369                }
15370                if (newReceivers != null && newReceivers.size() == 0) {
15371                    newReceivers = null;
15372                }
15373                if (receivers == null) {
15374                    receivers = newReceivers;
15375                } else if (newReceivers != null) {
15376                    // We need to concatenate the additional receivers
15377                    // found with what we have do far.  This would be easy,
15378                    // but we also need to de-dup any receivers that are
15379                    // singleUser.
15380                    if (!scannedFirstReceivers) {
15381                        // Collect any single user receivers we had already retrieved.
15382                        scannedFirstReceivers = true;
15383                        for (int i=0; i<receivers.size(); i++) {
15384                            ResolveInfo ri = receivers.get(i);
15385                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15386                                ComponentName cn = new ComponentName(
15387                                        ri.activityInfo.packageName, ri.activityInfo.name);
15388                                if (singleUserReceivers == null) {
15389                                    singleUserReceivers = new HashSet<ComponentName>();
15390                                }
15391                                singleUserReceivers.add(cn);
15392                            }
15393                        }
15394                    }
15395                    // Add the new results to the existing results, tracking
15396                    // and de-dupping single user receivers.
15397                    for (int i=0; i<newReceivers.size(); i++) {
15398                        ResolveInfo ri = newReceivers.get(i);
15399                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15400                            ComponentName cn = new ComponentName(
15401                                    ri.activityInfo.packageName, ri.activityInfo.name);
15402                            if (singleUserReceivers == null) {
15403                                singleUserReceivers = new HashSet<ComponentName>();
15404                            }
15405                            if (!singleUserReceivers.contains(cn)) {
15406                                singleUserReceivers.add(cn);
15407                                receivers.add(ri);
15408                            }
15409                        } else {
15410                            receivers.add(ri);
15411                        }
15412                    }
15413                }
15414            }
15415        } catch (RemoteException ex) {
15416            // pm is in same process, this will never happen.
15417        }
15418        return receivers;
15419    }
15420
15421    private final int broadcastIntentLocked(ProcessRecord callerApp,
15422            String callerPackage, Intent intent, String resolvedType,
15423            IIntentReceiver resultTo, int resultCode, String resultData,
15424            Bundle map, String requiredPermission, int appOp,
15425            boolean ordered, boolean sticky, int callingPid, int callingUid,
15426            int userId) {
15427        intent = new Intent(intent);
15428
15429        // By default broadcasts do not go to stopped apps.
15430        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15431
15432        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15433            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15434            + " ordered=" + ordered + " userid=" + userId);
15435        if ((resultTo != null) && !ordered) {
15436            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15437        }
15438
15439        userId = handleIncomingUser(callingPid, callingUid, userId,
15440                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15441
15442        // Make sure that the user who is receiving this broadcast is started.
15443        // If not, we will just skip it.
15444
15445        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15446            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15447                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15448                Slog.w(TAG, "Skipping broadcast of " + intent
15449                        + ": user " + userId + " is stopped");
15450                return ActivityManager.BROADCAST_SUCCESS;
15451            }
15452        }
15453
15454        /*
15455         * Prevent non-system code (defined here to be non-persistent
15456         * processes) from sending protected broadcasts.
15457         */
15458        int callingAppId = UserHandle.getAppId(callingUid);
15459        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15460            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15461            || callingAppId == Process.NFC_UID || callingUid == 0) {
15462            // Always okay.
15463        } else if (callerApp == null || !callerApp.persistent) {
15464            try {
15465                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15466                        intent.getAction())) {
15467                    String msg = "Permission Denial: not allowed to send broadcast "
15468                            + intent.getAction() + " from pid="
15469                            + callingPid + ", uid=" + callingUid;
15470                    Slog.w(TAG, msg);
15471                    throw new SecurityException(msg);
15472                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15473                    // Special case for compatibility: we don't want apps to send this,
15474                    // but historically it has not been protected and apps may be using it
15475                    // to poke their own app widget.  So, instead of making it protected,
15476                    // just limit it to the caller.
15477                    if (callerApp == null) {
15478                        String msg = "Permission Denial: not allowed to send broadcast "
15479                                + intent.getAction() + " from unknown caller.";
15480                        Slog.w(TAG, msg);
15481                        throw new SecurityException(msg);
15482                    } else if (intent.getComponent() != null) {
15483                        // They are good enough to send to an explicit component...  verify
15484                        // it is being sent to the calling app.
15485                        if (!intent.getComponent().getPackageName().equals(
15486                                callerApp.info.packageName)) {
15487                            String msg = "Permission Denial: not allowed to send broadcast "
15488                                    + intent.getAction() + " to "
15489                                    + intent.getComponent().getPackageName() + " from "
15490                                    + callerApp.info.packageName;
15491                            Slog.w(TAG, msg);
15492                            throw new SecurityException(msg);
15493                        }
15494                    } else {
15495                        // Limit broadcast to their own package.
15496                        intent.setPackage(callerApp.info.packageName);
15497                    }
15498                }
15499            } catch (RemoteException e) {
15500                Slog.w(TAG, "Remote exception", e);
15501                return ActivityManager.BROADCAST_SUCCESS;
15502            }
15503        }
15504
15505        // Handle special intents: if this broadcast is from the package
15506        // manager about a package being removed, we need to remove all of
15507        // its activities from the history stack.
15508        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15509                intent.getAction());
15510        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15511                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15512                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15513                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15514                || uidRemoved) {
15515            if (checkComponentPermission(
15516                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15517                    callingPid, callingUid, -1, true)
15518                    == PackageManager.PERMISSION_GRANTED) {
15519                if (uidRemoved) {
15520                    final Bundle intentExtras = intent.getExtras();
15521                    final int uid = intentExtras != null
15522                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15523                    if (uid >= 0) {
15524                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15525                        synchronized (bs) {
15526                            bs.removeUidStatsLocked(uid);
15527                        }
15528                        mAppOpsService.uidRemoved(uid);
15529                    }
15530                } else {
15531                    // If resources are unavailable just force stop all
15532                    // those packages and flush the attribute cache as well.
15533                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15534                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15535                        if (list != null && (list.length > 0)) {
15536                            for (String pkg : list) {
15537                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15538                                        "storage unmount");
15539                            }
15540                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15541                            sendPackageBroadcastLocked(
15542                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15543                        }
15544                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15545                            intent.getAction())) {
15546                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15547                    } else {
15548                        Uri data = intent.getData();
15549                        String ssp;
15550                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15551                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15552                                    intent.getAction());
15553                            boolean fullUninstall = removed &&
15554                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15555                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15556                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15557                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15558                                        false, fullUninstall, userId,
15559                                        removed ? "pkg removed" : "pkg changed");
15560                            }
15561                            if (removed) {
15562                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15563                                        new String[] {ssp}, userId);
15564                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15565                                    mAppOpsService.packageRemoved(
15566                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15567
15568                                    // Remove all permissions granted from/to this package
15569                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15570                                }
15571                            }
15572                        }
15573                    }
15574                }
15575            } else {
15576                String msg = "Permission Denial: " + intent.getAction()
15577                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15578                        + ", uid=" + callingUid + ")"
15579                        + " requires "
15580                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15581                Slog.w(TAG, msg);
15582                throw new SecurityException(msg);
15583            }
15584
15585        // Special case for adding a package: by default turn on compatibility
15586        // mode.
15587        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15588            Uri data = intent.getData();
15589            String ssp;
15590            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15591                mCompatModePackages.handlePackageAddedLocked(ssp,
15592                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15593            }
15594        }
15595
15596        /*
15597         * If this is the time zone changed action, queue up a message that will reset the timezone
15598         * of all currently running processes. This message will get queued up before the broadcast
15599         * happens.
15600         */
15601        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15602            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15603        }
15604
15605        /*
15606         * If the user set the time, let all running processes know.
15607         */
15608        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15609            final int is24Hour = intent.getBooleanExtra(
15610                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15611            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15612            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15613            synchronized (stats) {
15614                stats.noteCurrentTimeChangedLocked();
15615            }
15616        }
15617
15618        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15619            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15620        }
15621
15622        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15623            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15624            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15625        }
15626
15627        // Add to the sticky list if requested.
15628        if (sticky) {
15629            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15630                    callingPid, callingUid)
15631                    != PackageManager.PERMISSION_GRANTED) {
15632                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15633                        + callingPid + ", uid=" + callingUid
15634                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15635                Slog.w(TAG, msg);
15636                throw new SecurityException(msg);
15637            }
15638            if (requiredPermission != null) {
15639                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15640                        + " and enforce permission " + requiredPermission);
15641                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15642            }
15643            if (intent.getComponent() != null) {
15644                throw new SecurityException(
15645                        "Sticky broadcasts can't target a specific component");
15646            }
15647            // We use userId directly here, since the "all" target is maintained
15648            // as a separate set of sticky broadcasts.
15649            if (userId != UserHandle.USER_ALL) {
15650                // But first, if this is not a broadcast to all users, then
15651                // make sure it doesn't conflict with an existing broadcast to
15652                // all users.
15653                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15654                        UserHandle.USER_ALL);
15655                if (stickies != null) {
15656                    ArrayList<Intent> list = stickies.get(intent.getAction());
15657                    if (list != null) {
15658                        int N = list.size();
15659                        int i;
15660                        for (i=0; i<N; i++) {
15661                            if (intent.filterEquals(list.get(i))) {
15662                                throw new IllegalArgumentException(
15663                                        "Sticky broadcast " + intent + " for user "
15664                                        + userId + " conflicts with existing global broadcast");
15665                            }
15666                        }
15667                    }
15668                }
15669            }
15670            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15671            if (stickies == null) {
15672                stickies = new ArrayMap<String, ArrayList<Intent>>();
15673                mStickyBroadcasts.put(userId, stickies);
15674            }
15675            ArrayList<Intent> list = stickies.get(intent.getAction());
15676            if (list == null) {
15677                list = new ArrayList<Intent>();
15678                stickies.put(intent.getAction(), list);
15679            }
15680            int N = list.size();
15681            int i;
15682            for (i=0; i<N; i++) {
15683                if (intent.filterEquals(list.get(i))) {
15684                    // This sticky already exists, replace it.
15685                    list.set(i, new Intent(intent));
15686                    break;
15687                }
15688            }
15689            if (i >= N) {
15690                list.add(new Intent(intent));
15691            }
15692        }
15693
15694        int[] users;
15695        if (userId == UserHandle.USER_ALL) {
15696            // Caller wants broadcast to go to all started users.
15697            users = mStartedUserArray;
15698        } else {
15699            // Caller wants broadcast to go to one specific user.
15700            users = new int[] {userId};
15701        }
15702
15703        // Figure out who all will receive this broadcast.
15704        List receivers = null;
15705        List<BroadcastFilter> registeredReceivers = null;
15706        // Need to resolve the intent to interested receivers...
15707        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15708                 == 0) {
15709            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15710        }
15711        if (intent.getComponent() == null) {
15712            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15713                // Query one target user at a time, excluding shell-restricted users
15714                UserManagerService ums = getUserManagerLocked();
15715                for (int i = 0; i < users.length; i++) {
15716                    if (ums.hasUserRestriction(
15717                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15718                        continue;
15719                    }
15720                    List<BroadcastFilter> registeredReceiversForUser =
15721                            mReceiverResolver.queryIntent(intent,
15722                                    resolvedType, false, users[i]);
15723                    if (registeredReceivers == null) {
15724                        registeredReceivers = registeredReceiversForUser;
15725                    } else if (registeredReceiversForUser != null) {
15726                        registeredReceivers.addAll(registeredReceiversForUser);
15727                    }
15728                }
15729            } else {
15730                registeredReceivers = mReceiverResolver.queryIntent(intent,
15731                        resolvedType, false, userId);
15732            }
15733        }
15734
15735        final boolean replacePending =
15736                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15737
15738        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15739                + " replacePending=" + replacePending);
15740
15741        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15742        if (!ordered && NR > 0) {
15743            // If we are not serializing this broadcast, then send the
15744            // registered receivers separately so they don't wait for the
15745            // components to be launched.
15746            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15747            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15748                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15749                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15750                    ordered, sticky, false, userId);
15751            if (DEBUG_BROADCAST) Slog.v(
15752                    TAG, "Enqueueing parallel broadcast " + r);
15753            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15754            if (!replaced) {
15755                queue.enqueueParallelBroadcastLocked(r);
15756                queue.scheduleBroadcastsLocked();
15757            }
15758            registeredReceivers = null;
15759            NR = 0;
15760        }
15761
15762        // Merge into one list.
15763        int ir = 0;
15764        if (receivers != null) {
15765            // A special case for PACKAGE_ADDED: do not allow the package
15766            // being added to see this broadcast.  This prevents them from
15767            // using this as a back door to get run as soon as they are
15768            // installed.  Maybe in the future we want to have a special install
15769            // broadcast or such for apps, but we'd like to deliberately make
15770            // this decision.
15771            String skipPackages[] = null;
15772            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15773                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15774                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15775                Uri data = intent.getData();
15776                if (data != null) {
15777                    String pkgName = data.getSchemeSpecificPart();
15778                    if (pkgName != null) {
15779                        skipPackages = new String[] { pkgName };
15780                    }
15781                }
15782            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15783                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15784            }
15785            if (skipPackages != null && (skipPackages.length > 0)) {
15786                for (String skipPackage : skipPackages) {
15787                    if (skipPackage != null) {
15788                        int NT = receivers.size();
15789                        for (int it=0; it<NT; it++) {
15790                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15791                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15792                                receivers.remove(it);
15793                                it--;
15794                                NT--;
15795                            }
15796                        }
15797                    }
15798                }
15799            }
15800
15801            int NT = receivers != null ? receivers.size() : 0;
15802            int it = 0;
15803            ResolveInfo curt = null;
15804            BroadcastFilter curr = null;
15805            while (it < NT && ir < NR) {
15806                if (curt == null) {
15807                    curt = (ResolveInfo)receivers.get(it);
15808                }
15809                if (curr == null) {
15810                    curr = registeredReceivers.get(ir);
15811                }
15812                if (curr.getPriority() >= curt.priority) {
15813                    // Insert this broadcast record into the final list.
15814                    receivers.add(it, curr);
15815                    ir++;
15816                    curr = null;
15817                    it++;
15818                    NT++;
15819                } else {
15820                    // Skip to the next ResolveInfo in the final list.
15821                    it++;
15822                    curt = null;
15823                }
15824            }
15825        }
15826        while (ir < NR) {
15827            if (receivers == null) {
15828                receivers = new ArrayList();
15829            }
15830            receivers.add(registeredReceivers.get(ir));
15831            ir++;
15832        }
15833
15834        if ((receivers != null && receivers.size() > 0)
15835                || resultTo != null) {
15836            BroadcastQueue queue = broadcastQueueForIntent(intent);
15837            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15838                    callerPackage, callingPid, callingUid, resolvedType,
15839                    requiredPermission, appOp, receivers, resultTo, resultCode,
15840                    resultData, map, ordered, sticky, false, userId);
15841            if (DEBUG_BROADCAST) Slog.v(
15842                    TAG, "Enqueueing ordered broadcast " + r
15843                    + ": prev had " + queue.mOrderedBroadcasts.size());
15844            if (DEBUG_BROADCAST) {
15845                int seq = r.intent.getIntExtra("seq", -1);
15846                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15847            }
15848            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15849            if (!replaced) {
15850                queue.enqueueOrderedBroadcastLocked(r);
15851                queue.scheduleBroadcastsLocked();
15852            }
15853        }
15854
15855        return ActivityManager.BROADCAST_SUCCESS;
15856    }
15857
15858    final Intent verifyBroadcastLocked(Intent intent) {
15859        // Refuse possible leaked file descriptors
15860        if (intent != null && intent.hasFileDescriptors() == true) {
15861            throw new IllegalArgumentException("File descriptors passed in Intent");
15862        }
15863
15864        int flags = intent.getFlags();
15865
15866        if (!mProcessesReady) {
15867            // if the caller really truly claims to know what they're doing, go
15868            // ahead and allow the broadcast without launching any receivers
15869            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15870                intent = new Intent(intent);
15871                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15872            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15873                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15874                        + " before boot completion");
15875                throw new IllegalStateException("Cannot broadcast before boot completed");
15876            }
15877        }
15878
15879        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15880            throw new IllegalArgumentException(
15881                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15882        }
15883
15884        return intent;
15885    }
15886
15887    public final int broadcastIntent(IApplicationThread caller,
15888            Intent intent, String resolvedType, IIntentReceiver resultTo,
15889            int resultCode, String resultData, Bundle map,
15890            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15891        enforceNotIsolatedCaller("broadcastIntent");
15892        synchronized(this) {
15893            intent = verifyBroadcastLocked(intent);
15894
15895            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15896            final int callingPid = Binder.getCallingPid();
15897            final int callingUid = Binder.getCallingUid();
15898            final long origId = Binder.clearCallingIdentity();
15899            int res = broadcastIntentLocked(callerApp,
15900                    callerApp != null ? callerApp.info.packageName : null,
15901                    intent, resolvedType, resultTo,
15902                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15903                    callingPid, callingUid, userId);
15904            Binder.restoreCallingIdentity(origId);
15905            return res;
15906        }
15907    }
15908
15909    int broadcastIntentInPackage(String packageName, int uid,
15910            Intent intent, String resolvedType, IIntentReceiver resultTo,
15911            int resultCode, String resultData, Bundle map,
15912            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15913        synchronized(this) {
15914            intent = verifyBroadcastLocked(intent);
15915
15916            final long origId = Binder.clearCallingIdentity();
15917            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15918                    resultTo, resultCode, resultData, map, requiredPermission,
15919                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15920            Binder.restoreCallingIdentity(origId);
15921            return res;
15922        }
15923    }
15924
15925    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15926        // Refuse possible leaked file descriptors
15927        if (intent != null && intent.hasFileDescriptors() == true) {
15928            throw new IllegalArgumentException("File descriptors passed in Intent");
15929        }
15930
15931        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15932                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15933
15934        synchronized(this) {
15935            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15936                    != PackageManager.PERMISSION_GRANTED) {
15937                String msg = "Permission Denial: unbroadcastIntent() from pid="
15938                        + Binder.getCallingPid()
15939                        + ", uid=" + Binder.getCallingUid()
15940                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15941                Slog.w(TAG, msg);
15942                throw new SecurityException(msg);
15943            }
15944            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15945            if (stickies != null) {
15946                ArrayList<Intent> list = stickies.get(intent.getAction());
15947                if (list != null) {
15948                    int N = list.size();
15949                    int i;
15950                    for (i=0; i<N; i++) {
15951                        if (intent.filterEquals(list.get(i))) {
15952                            list.remove(i);
15953                            break;
15954                        }
15955                    }
15956                    if (list.size() <= 0) {
15957                        stickies.remove(intent.getAction());
15958                    }
15959                }
15960                if (stickies.size() <= 0) {
15961                    mStickyBroadcasts.remove(userId);
15962                }
15963            }
15964        }
15965    }
15966
15967    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15968            String resultData, Bundle resultExtras, boolean resultAbort) {
15969        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15970        if (r == null) {
15971            Slog.w(TAG, "finishReceiver called but not found on queue");
15972            return false;
15973        }
15974
15975        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15976    }
15977
15978    void backgroundServicesFinishedLocked(int userId) {
15979        for (BroadcastQueue queue : mBroadcastQueues) {
15980            queue.backgroundServicesFinishedLocked(userId);
15981        }
15982    }
15983
15984    public void finishReceiver(IBinder who, int resultCode, String resultData,
15985            Bundle resultExtras, boolean resultAbort) {
15986        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15987
15988        // Refuse possible leaked file descriptors
15989        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15990            throw new IllegalArgumentException("File descriptors passed in Bundle");
15991        }
15992
15993        final long origId = Binder.clearCallingIdentity();
15994        try {
15995            boolean doNext = false;
15996            BroadcastRecord r;
15997
15998            synchronized(this) {
15999                r = broadcastRecordForReceiverLocked(who);
16000                if (r != null) {
16001                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16002                        resultData, resultExtras, resultAbort, true);
16003                }
16004            }
16005
16006            if (doNext) {
16007                r.queue.processNextBroadcast(false);
16008            }
16009            trimApplications();
16010        } finally {
16011            Binder.restoreCallingIdentity(origId);
16012        }
16013    }
16014
16015    // =========================================================
16016    // INSTRUMENTATION
16017    // =========================================================
16018
16019    public boolean startInstrumentation(ComponentName className,
16020            String profileFile, int flags, Bundle arguments,
16021            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16022            int userId, String abiOverride) {
16023        enforceNotIsolatedCaller("startInstrumentation");
16024        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16025                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16026        // Refuse possible leaked file descriptors
16027        if (arguments != null && arguments.hasFileDescriptors()) {
16028            throw new IllegalArgumentException("File descriptors passed in Bundle");
16029        }
16030
16031        synchronized(this) {
16032            InstrumentationInfo ii = null;
16033            ApplicationInfo ai = null;
16034            try {
16035                ii = mContext.getPackageManager().getInstrumentationInfo(
16036                    className, STOCK_PM_FLAGS);
16037                ai = AppGlobals.getPackageManager().getApplicationInfo(
16038                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16039            } catch (PackageManager.NameNotFoundException e) {
16040            } catch (RemoteException e) {
16041            }
16042            if (ii == null) {
16043                reportStartInstrumentationFailure(watcher, className,
16044                        "Unable to find instrumentation info for: " + className);
16045                return false;
16046            }
16047            if (ai == null) {
16048                reportStartInstrumentationFailure(watcher, className,
16049                        "Unable to find instrumentation target package: " + ii.targetPackage);
16050                return false;
16051            }
16052
16053            int match = mContext.getPackageManager().checkSignatures(
16054                    ii.targetPackage, ii.packageName);
16055            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16056                String msg = "Permission Denial: starting instrumentation "
16057                        + className + " from pid="
16058                        + Binder.getCallingPid()
16059                        + ", uid=" + Binder.getCallingPid()
16060                        + " not allowed because package " + ii.packageName
16061                        + " does not have a signature matching the target "
16062                        + ii.targetPackage;
16063                reportStartInstrumentationFailure(watcher, className, msg);
16064                throw new SecurityException(msg);
16065            }
16066
16067            final long origId = Binder.clearCallingIdentity();
16068            // Instrumentation can kill and relaunch even persistent processes
16069            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16070                    "start instr");
16071            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16072            app.instrumentationClass = className;
16073            app.instrumentationInfo = ai;
16074            app.instrumentationProfileFile = profileFile;
16075            app.instrumentationArguments = arguments;
16076            app.instrumentationWatcher = watcher;
16077            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16078            app.instrumentationResultClass = className;
16079            Binder.restoreCallingIdentity(origId);
16080        }
16081
16082        return true;
16083    }
16084
16085    /**
16086     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16087     * error to the logs, but if somebody is watching, send the report there too.  This enables
16088     * the "am" command to report errors with more information.
16089     *
16090     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16091     * @param cn The component name of the instrumentation.
16092     * @param report The error report.
16093     */
16094    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16095            ComponentName cn, String report) {
16096        Slog.w(TAG, report);
16097        try {
16098            if (watcher != null) {
16099                Bundle results = new Bundle();
16100                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16101                results.putString("Error", report);
16102                watcher.instrumentationStatus(cn, -1, results);
16103            }
16104        } catch (RemoteException e) {
16105            Slog.w(TAG, e);
16106        }
16107    }
16108
16109    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16110        if (app.instrumentationWatcher != null) {
16111            try {
16112                // NOTE:  IInstrumentationWatcher *must* be oneway here
16113                app.instrumentationWatcher.instrumentationFinished(
16114                    app.instrumentationClass,
16115                    resultCode,
16116                    results);
16117            } catch (RemoteException e) {
16118            }
16119        }
16120        if (app.instrumentationUiAutomationConnection != null) {
16121            try {
16122                app.instrumentationUiAutomationConnection.shutdown();
16123            } catch (RemoteException re) {
16124                /* ignore */
16125            }
16126            // Only a UiAutomation can set this flag and now that
16127            // it is finished we make sure it is reset to its default.
16128            mUserIsMonkey = false;
16129        }
16130        app.instrumentationWatcher = null;
16131        app.instrumentationUiAutomationConnection = null;
16132        app.instrumentationClass = null;
16133        app.instrumentationInfo = null;
16134        app.instrumentationProfileFile = null;
16135        app.instrumentationArguments = null;
16136
16137        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16138                "finished inst");
16139    }
16140
16141    public void finishInstrumentation(IApplicationThread target,
16142            int resultCode, Bundle results) {
16143        int userId = UserHandle.getCallingUserId();
16144        // Refuse possible leaked file descriptors
16145        if (results != null && results.hasFileDescriptors()) {
16146            throw new IllegalArgumentException("File descriptors passed in Intent");
16147        }
16148
16149        synchronized(this) {
16150            ProcessRecord app = getRecordForAppLocked(target);
16151            if (app == null) {
16152                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16153                return;
16154            }
16155            final long origId = Binder.clearCallingIdentity();
16156            finishInstrumentationLocked(app, resultCode, results);
16157            Binder.restoreCallingIdentity(origId);
16158        }
16159    }
16160
16161    // =========================================================
16162    // CONFIGURATION
16163    // =========================================================
16164
16165    public ConfigurationInfo getDeviceConfigurationInfo() {
16166        ConfigurationInfo config = new ConfigurationInfo();
16167        synchronized (this) {
16168            config.reqTouchScreen = mConfiguration.touchscreen;
16169            config.reqKeyboardType = mConfiguration.keyboard;
16170            config.reqNavigation = mConfiguration.navigation;
16171            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16172                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16173                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16174            }
16175            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16176                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16177                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16178            }
16179            config.reqGlEsVersion = GL_ES_VERSION;
16180        }
16181        return config;
16182    }
16183
16184    ActivityStack getFocusedStack() {
16185        return mStackSupervisor.getFocusedStack();
16186    }
16187
16188    public Configuration getConfiguration() {
16189        Configuration ci;
16190        synchronized(this) {
16191            ci = new Configuration(mConfiguration);
16192        }
16193        return ci;
16194    }
16195
16196    public void updatePersistentConfiguration(Configuration values) {
16197        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16198                "updateConfiguration()");
16199        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16200                "updateConfiguration()");
16201        if (values == null) {
16202            throw new NullPointerException("Configuration must not be null");
16203        }
16204
16205        synchronized(this) {
16206            final long origId = Binder.clearCallingIdentity();
16207            updateConfigurationLocked(values, null, true, false);
16208            Binder.restoreCallingIdentity(origId);
16209        }
16210    }
16211
16212    public void updateConfiguration(Configuration values) {
16213        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16214                "updateConfiguration()");
16215
16216        synchronized(this) {
16217            if (values == null && mWindowManager != null) {
16218                // sentinel: fetch the current configuration from the window manager
16219                values = mWindowManager.computeNewConfiguration();
16220            }
16221
16222            if (mWindowManager != null) {
16223                mProcessList.applyDisplaySize(mWindowManager);
16224            }
16225
16226            final long origId = Binder.clearCallingIdentity();
16227            if (values != null) {
16228                Settings.System.clearConfiguration(values);
16229            }
16230            updateConfigurationLocked(values, null, false, false);
16231            Binder.restoreCallingIdentity(origId);
16232        }
16233    }
16234
16235    /**
16236     * Do either or both things: (1) change the current configuration, and (2)
16237     * make sure the given activity is running with the (now) current
16238     * configuration.  Returns true if the activity has been left running, or
16239     * false if <var>starting</var> is being destroyed to match the new
16240     * configuration.
16241     * @param persistent TODO
16242     */
16243    boolean updateConfigurationLocked(Configuration values,
16244            ActivityRecord starting, boolean persistent, boolean initLocale) {
16245        int changes = 0;
16246
16247        if (values != null) {
16248            Configuration newConfig = new Configuration(mConfiguration);
16249            changes = newConfig.updateFrom(values);
16250            if (changes != 0) {
16251                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16252                    Slog.i(TAG, "Updating configuration to: " + values);
16253                }
16254
16255                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16256
16257                if (values.locale != null && !initLocale) {
16258                    saveLocaleLocked(values.locale,
16259                                     !values.locale.equals(mConfiguration.locale),
16260                                     values.userSetLocale);
16261                }
16262
16263                mConfigurationSeq++;
16264                if (mConfigurationSeq <= 0) {
16265                    mConfigurationSeq = 1;
16266                }
16267                newConfig.seq = mConfigurationSeq;
16268                mConfiguration = newConfig;
16269                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16270                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16271                //mUsageStatsService.noteStartConfig(newConfig);
16272
16273                final Configuration configCopy = new Configuration(mConfiguration);
16274
16275                // TODO: If our config changes, should we auto dismiss any currently
16276                // showing dialogs?
16277                mShowDialogs = shouldShowDialogs(newConfig);
16278
16279                AttributeCache ac = AttributeCache.instance();
16280                if (ac != null) {
16281                    ac.updateConfiguration(configCopy);
16282                }
16283
16284                // Make sure all resources in our process are updated
16285                // right now, so that anyone who is going to retrieve
16286                // resource values after we return will be sure to get
16287                // the new ones.  This is especially important during
16288                // boot, where the first config change needs to guarantee
16289                // all resources have that config before following boot
16290                // code is executed.
16291                mSystemThread.applyConfigurationToResources(configCopy);
16292
16293                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16294                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16295                    msg.obj = new Configuration(configCopy);
16296                    mHandler.sendMessage(msg);
16297                }
16298
16299                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16300                    ProcessRecord app = mLruProcesses.get(i);
16301                    try {
16302                        if (app.thread != null) {
16303                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16304                                    + app.processName + " new config " + mConfiguration);
16305                            app.thread.scheduleConfigurationChanged(configCopy);
16306                        }
16307                    } catch (Exception e) {
16308                    }
16309                }
16310                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16311                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16312                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16313                        | Intent.FLAG_RECEIVER_FOREGROUND);
16314                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16315                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16316                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16317                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16318                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16319                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16320                    broadcastIntentLocked(null, null, intent,
16321                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16322                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16323                }
16324            }
16325        }
16326
16327        boolean kept = true;
16328        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16329        // mainStack is null during startup.
16330        if (mainStack != null) {
16331            if (changes != 0 && starting == null) {
16332                // If the configuration changed, and the caller is not already
16333                // in the process of starting an activity, then find the top
16334                // activity to check if its configuration needs to change.
16335                starting = mainStack.topRunningActivityLocked(null);
16336            }
16337
16338            if (starting != null) {
16339                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16340                // And we need to make sure at this point that all other activities
16341                // are made visible with the correct configuration.
16342                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16343            }
16344        }
16345
16346        if (values != null && mWindowManager != null) {
16347            mWindowManager.setNewConfiguration(mConfiguration);
16348        }
16349
16350        return kept;
16351    }
16352
16353    /**
16354     * Decide based on the configuration whether we should shouw the ANR,
16355     * crash, etc dialogs.  The idea is that if there is no affordnace to
16356     * press the on-screen buttons, we shouldn't show the dialog.
16357     *
16358     * A thought: SystemUI might also want to get told about this, the Power
16359     * dialog / global actions also might want different behaviors.
16360     */
16361    private static final boolean shouldShowDialogs(Configuration config) {
16362        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16363                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16364    }
16365
16366    /**
16367     * Save the locale.  You must be inside a synchronized (this) block.
16368     */
16369    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16370        if(isDiff) {
16371            SystemProperties.set("user.language", l.getLanguage());
16372            SystemProperties.set("user.region", l.getCountry());
16373        }
16374
16375        if(isPersist) {
16376            SystemProperties.set("persist.sys.language", l.getLanguage());
16377            SystemProperties.set("persist.sys.country", l.getCountry());
16378            SystemProperties.set("persist.sys.localevar", l.getVariant());
16379
16380            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16381        }
16382    }
16383
16384    @Override
16385    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16386        synchronized (this) {
16387            ActivityRecord srec = ActivityRecord.forToken(token);
16388            if (srec.task != null && srec.task.stack != null) {
16389                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16390            }
16391        }
16392        return false;
16393    }
16394
16395    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16396            Intent resultData) {
16397
16398        synchronized (this) {
16399            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16400            if (stack != null) {
16401                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16402            }
16403            return false;
16404        }
16405    }
16406
16407    public int getLaunchedFromUid(IBinder activityToken) {
16408        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16409        if (srec == null) {
16410            return -1;
16411        }
16412        return srec.launchedFromUid;
16413    }
16414
16415    public String getLaunchedFromPackage(IBinder activityToken) {
16416        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16417        if (srec == null) {
16418            return null;
16419        }
16420        return srec.launchedFromPackage;
16421    }
16422
16423    // =========================================================
16424    // LIFETIME MANAGEMENT
16425    // =========================================================
16426
16427    // Returns which broadcast queue the app is the current [or imminent] receiver
16428    // on, or 'null' if the app is not an active broadcast recipient.
16429    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16430        BroadcastRecord r = app.curReceiver;
16431        if (r != null) {
16432            return r.queue;
16433        }
16434
16435        // It's not the current receiver, but it might be starting up to become one
16436        synchronized (this) {
16437            for (BroadcastQueue queue : mBroadcastQueues) {
16438                r = queue.mPendingBroadcast;
16439                if (r != null && r.curApp == app) {
16440                    // found it; report which queue it's in
16441                    return queue;
16442                }
16443            }
16444        }
16445
16446        return null;
16447    }
16448
16449    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16450            boolean doingAll, long now) {
16451        if (mAdjSeq == app.adjSeq) {
16452            // This adjustment has already been computed.
16453            return app.curRawAdj;
16454        }
16455
16456        if (app.thread == null) {
16457            app.adjSeq = mAdjSeq;
16458            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16459            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16460            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16461        }
16462
16463        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16464        app.adjSource = null;
16465        app.adjTarget = null;
16466        app.empty = false;
16467        app.cached = false;
16468
16469        final int activitiesSize = app.activities.size();
16470
16471        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16472            // The max adjustment doesn't allow this app to be anything
16473            // below foreground, so it is not worth doing work for it.
16474            app.adjType = "fixed";
16475            app.adjSeq = mAdjSeq;
16476            app.curRawAdj = app.maxAdj;
16477            app.foregroundActivities = false;
16478            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16479            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16480            // System processes can do UI, and when they do we want to have
16481            // them trim their memory after the user leaves the UI.  To
16482            // facilitate this, here we need to determine whether or not it
16483            // is currently showing UI.
16484            app.systemNoUi = true;
16485            if (app == TOP_APP) {
16486                app.systemNoUi = false;
16487            } else if (activitiesSize > 0) {
16488                for (int j = 0; j < activitiesSize; j++) {
16489                    final ActivityRecord r = app.activities.get(j);
16490                    if (r.visible) {
16491                        app.systemNoUi = false;
16492                    }
16493                }
16494            }
16495            if (!app.systemNoUi) {
16496                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16497            }
16498            return (app.curAdj=app.maxAdj);
16499        }
16500
16501        app.systemNoUi = false;
16502
16503        // Determine the importance of the process, starting with most
16504        // important to least, and assign an appropriate OOM adjustment.
16505        int adj;
16506        int schedGroup;
16507        int procState;
16508        boolean foregroundActivities = false;
16509        BroadcastQueue queue;
16510        if (app == TOP_APP) {
16511            // The last app on the list is the foreground app.
16512            adj = ProcessList.FOREGROUND_APP_ADJ;
16513            schedGroup = Process.THREAD_GROUP_DEFAULT;
16514            app.adjType = "top-activity";
16515            foregroundActivities = true;
16516            procState = ActivityManager.PROCESS_STATE_TOP;
16517        } else if (app.instrumentationClass != null) {
16518            // Don't want to kill running instrumentation.
16519            adj = ProcessList.FOREGROUND_APP_ADJ;
16520            schedGroup = Process.THREAD_GROUP_DEFAULT;
16521            app.adjType = "instrumentation";
16522            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16523        } else if ((queue = isReceivingBroadcast(app)) != null) {
16524            // An app that is currently receiving a broadcast also
16525            // counts as being in the foreground for OOM killer purposes.
16526            // It's placed in a sched group based on the nature of the
16527            // broadcast as reflected by which queue it's active in.
16528            adj = ProcessList.FOREGROUND_APP_ADJ;
16529            schedGroup = (queue == mFgBroadcastQueue)
16530                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16531            app.adjType = "broadcast";
16532            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16533        } else if (app.executingServices.size() > 0) {
16534            // An app that is currently executing a service callback also
16535            // counts as being in the foreground.
16536            adj = ProcessList.FOREGROUND_APP_ADJ;
16537            schedGroup = app.execServicesFg ?
16538                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16539            app.adjType = "exec-service";
16540            procState = ActivityManager.PROCESS_STATE_SERVICE;
16541            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16542        } else {
16543            // As far as we know the process is empty.  We may change our mind later.
16544            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16545            // At this point we don't actually know the adjustment.  Use the cached adj
16546            // value that the caller wants us to.
16547            adj = cachedAdj;
16548            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16549            app.cached = true;
16550            app.empty = true;
16551            app.adjType = "cch-empty";
16552        }
16553
16554        // Examine all activities if not already foreground.
16555        if (!foregroundActivities && activitiesSize > 0) {
16556            for (int j = 0; j < activitiesSize; j++) {
16557                final ActivityRecord r = app.activities.get(j);
16558                if (r.app != app) {
16559                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16560                            + app + "?!?");
16561                    continue;
16562                }
16563                if (r.visible) {
16564                    // App has a visible activity; only upgrade adjustment.
16565                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16566                        adj = ProcessList.VISIBLE_APP_ADJ;
16567                        app.adjType = "visible";
16568                    }
16569                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16570                        procState = ActivityManager.PROCESS_STATE_TOP;
16571                    }
16572                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16573                    app.cached = false;
16574                    app.empty = false;
16575                    foregroundActivities = true;
16576                    break;
16577                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16578                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16579                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16580                        app.adjType = "pausing";
16581                    }
16582                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16583                        procState = ActivityManager.PROCESS_STATE_TOP;
16584                    }
16585                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16586                    app.cached = false;
16587                    app.empty = false;
16588                    foregroundActivities = true;
16589                } else if (r.state == ActivityState.STOPPING) {
16590                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16591                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16592                        app.adjType = "stopping";
16593                    }
16594                    // For the process state, we will at this point consider the
16595                    // process to be cached.  It will be cached either as an activity
16596                    // or empty depending on whether the activity is finishing.  We do
16597                    // this so that we can treat the process as cached for purposes of
16598                    // memory trimming (determing current memory level, trim command to
16599                    // send to process) since there can be an arbitrary number of stopping
16600                    // processes and they should soon all go into the cached state.
16601                    if (!r.finishing) {
16602                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16603                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16604                        }
16605                    }
16606                    app.cached = false;
16607                    app.empty = false;
16608                    foregroundActivities = true;
16609                } else {
16610                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16611                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16612                        app.adjType = "cch-act";
16613                    }
16614                }
16615            }
16616        }
16617
16618        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16619            if (app.foregroundServices) {
16620                // The user is aware of this app, so make it visible.
16621                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16622                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16623                app.cached = false;
16624                app.adjType = "fg-service";
16625                schedGroup = Process.THREAD_GROUP_DEFAULT;
16626            } else if (app.forcingToForeground != null) {
16627                // The user is aware of this app, so make it visible.
16628                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16629                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16630                app.cached = false;
16631                app.adjType = "force-fg";
16632                app.adjSource = app.forcingToForeground;
16633                schedGroup = Process.THREAD_GROUP_DEFAULT;
16634            }
16635        }
16636
16637        if (app == mHeavyWeightProcess) {
16638            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16639                // We don't want to kill the current heavy-weight process.
16640                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16641                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16642                app.cached = false;
16643                app.adjType = "heavy";
16644            }
16645            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16646                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16647            }
16648        }
16649
16650        if (app == mHomeProcess) {
16651            if (adj > ProcessList.HOME_APP_ADJ) {
16652                // This process is hosting what we currently consider to be the
16653                // home app, so we don't want to let it go into the background.
16654                adj = ProcessList.HOME_APP_ADJ;
16655                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16656                app.cached = false;
16657                app.adjType = "home";
16658            }
16659            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16660                procState = ActivityManager.PROCESS_STATE_HOME;
16661            }
16662        }
16663
16664        if (app == mPreviousProcess && app.activities.size() > 0) {
16665            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16666                // This was the previous process that showed UI to the user.
16667                // We want to try to keep it around more aggressively, to give
16668                // a good experience around switching between two apps.
16669                adj = ProcessList.PREVIOUS_APP_ADJ;
16670                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16671                app.cached = false;
16672                app.adjType = "previous";
16673            }
16674            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16675                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16676            }
16677        }
16678
16679        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16680                + " reason=" + app.adjType);
16681
16682        // By default, we use the computed adjustment.  It may be changed if
16683        // there are applications dependent on our services or providers, but
16684        // this gives us a baseline and makes sure we don't get into an
16685        // infinite recursion.
16686        app.adjSeq = mAdjSeq;
16687        app.curRawAdj = adj;
16688        app.hasStartedServices = false;
16689
16690        if (mBackupTarget != null && app == mBackupTarget.app) {
16691            // If possible we want to avoid killing apps while they're being backed up
16692            if (adj > ProcessList.BACKUP_APP_ADJ) {
16693                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16694                adj = ProcessList.BACKUP_APP_ADJ;
16695                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16696                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16697                }
16698                app.adjType = "backup";
16699                app.cached = false;
16700            }
16701            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16702                procState = ActivityManager.PROCESS_STATE_BACKUP;
16703            }
16704        }
16705
16706        boolean mayBeTop = false;
16707
16708        for (int is = app.services.size()-1;
16709                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16710                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16711                        || procState > ActivityManager.PROCESS_STATE_TOP);
16712                is--) {
16713            ServiceRecord s = app.services.valueAt(is);
16714            if (s.startRequested) {
16715                app.hasStartedServices = true;
16716                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16717                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16718                }
16719                if (app.hasShownUi && app != mHomeProcess) {
16720                    // If this process has shown some UI, let it immediately
16721                    // go to the LRU list because it may be pretty heavy with
16722                    // UI stuff.  We'll tag it with a label just to help
16723                    // debug and understand what is going on.
16724                    if (adj > ProcessList.SERVICE_ADJ) {
16725                        app.adjType = "cch-started-ui-services";
16726                    }
16727                } else {
16728                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16729                        // This service has seen some activity within
16730                        // recent memory, so we will keep its process ahead
16731                        // of the background processes.
16732                        if (adj > ProcessList.SERVICE_ADJ) {
16733                            adj = ProcessList.SERVICE_ADJ;
16734                            app.adjType = "started-services";
16735                            app.cached = false;
16736                        }
16737                    }
16738                    // If we have let the service slide into the background
16739                    // state, still have some text describing what it is doing
16740                    // even though the service no longer has an impact.
16741                    if (adj > ProcessList.SERVICE_ADJ) {
16742                        app.adjType = "cch-started-services";
16743                    }
16744                }
16745            }
16746            for (int conni = s.connections.size()-1;
16747                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16748                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16749                            || procState > ActivityManager.PROCESS_STATE_TOP);
16750                    conni--) {
16751                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16752                for (int i = 0;
16753                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16754                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16755                                || procState > ActivityManager.PROCESS_STATE_TOP);
16756                        i++) {
16757                    // XXX should compute this based on the max of
16758                    // all connected clients.
16759                    ConnectionRecord cr = clist.get(i);
16760                    if (cr.binding.client == app) {
16761                        // Binding to ourself is not interesting.
16762                        continue;
16763                    }
16764                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16765                        ProcessRecord client = cr.binding.client;
16766                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16767                                TOP_APP, doingAll, now);
16768                        int clientProcState = client.curProcState;
16769                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16770                            // If the other app is cached for any reason, for purposes here
16771                            // we are going to consider it empty.  The specific cached state
16772                            // doesn't propagate except under certain conditions.
16773                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16774                        }
16775                        String adjType = null;
16776                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16777                            // Not doing bind OOM management, so treat
16778                            // this guy more like a started service.
16779                            if (app.hasShownUi && app != mHomeProcess) {
16780                                // If this process has shown some UI, let it immediately
16781                                // go to the LRU list because it may be pretty heavy with
16782                                // UI stuff.  We'll tag it with a label just to help
16783                                // debug and understand what is going on.
16784                                if (adj > clientAdj) {
16785                                    adjType = "cch-bound-ui-services";
16786                                }
16787                                app.cached = false;
16788                                clientAdj = adj;
16789                                clientProcState = procState;
16790                            } else {
16791                                if (now >= (s.lastActivity
16792                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16793                                    // This service has not seen activity within
16794                                    // recent memory, so allow it to drop to the
16795                                    // LRU list if there is no other reason to keep
16796                                    // it around.  We'll also tag it with a label just
16797                                    // to help debug and undertand what is going on.
16798                                    if (adj > clientAdj) {
16799                                        adjType = "cch-bound-services";
16800                                    }
16801                                    clientAdj = adj;
16802                                }
16803                            }
16804                        }
16805                        if (adj > clientAdj) {
16806                            // If this process has recently shown UI, and
16807                            // the process that is binding to it is less
16808                            // important than being visible, then we don't
16809                            // care about the binding as much as we care
16810                            // about letting this process get into the LRU
16811                            // list to be killed and restarted if needed for
16812                            // memory.
16813                            if (app.hasShownUi && app != mHomeProcess
16814                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16815                                adjType = "cch-bound-ui-services";
16816                            } else {
16817                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16818                                        |Context.BIND_IMPORTANT)) != 0) {
16819                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16820                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16821                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16822                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16823                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16824                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16825                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16826                                    adj = clientAdj;
16827                                } else {
16828                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16829                                        adj = ProcessList.VISIBLE_APP_ADJ;
16830                                    }
16831                                }
16832                                if (!client.cached) {
16833                                    app.cached = false;
16834                                }
16835                                adjType = "service";
16836                            }
16837                        }
16838                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16839                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16840                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16841                            }
16842                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16843                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16844                                    // Special handling of clients who are in the top state.
16845                                    // We *may* want to consider this process to be in the
16846                                    // top state as well, but only if there is not another
16847                                    // reason for it to be running.  Being on the top is a
16848                                    // special state, meaning you are specifically running
16849                                    // for the current top app.  If the process is already
16850                                    // running in the background for some other reason, it
16851                                    // is more important to continue considering it to be
16852                                    // in the background state.
16853                                    mayBeTop = true;
16854                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16855                                } else {
16856                                    // Special handling for above-top states (persistent
16857                                    // processes).  These should not bring the current process
16858                                    // into the top state, since they are not on top.  Instead
16859                                    // give them the best state after that.
16860                                    clientProcState =
16861                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16862                                }
16863                            }
16864                        } else {
16865                            if (clientProcState <
16866                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16867                                clientProcState =
16868                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16869                            }
16870                        }
16871                        if (procState > clientProcState) {
16872                            procState = clientProcState;
16873                        }
16874                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16875                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16876                            app.pendingUiClean = true;
16877                        }
16878                        if (adjType != null) {
16879                            app.adjType = adjType;
16880                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16881                                    .REASON_SERVICE_IN_USE;
16882                            app.adjSource = cr.binding.client;
16883                            app.adjSourceProcState = clientProcState;
16884                            app.adjTarget = s.name;
16885                        }
16886                    }
16887                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16888                        app.treatLikeActivity = true;
16889                    }
16890                    final ActivityRecord a = cr.activity;
16891                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16892                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16893                                (a.visible || a.state == ActivityState.RESUMED
16894                                 || a.state == ActivityState.PAUSING)) {
16895                            adj = ProcessList.FOREGROUND_APP_ADJ;
16896                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16897                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16898                            }
16899                            app.cached = false;
16900                            app.adjType = "service";
16901                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16902                                    .REASON_SERVICE_IN_USE;
16903                            app.adjSource = a;
16904                            app.adjSourceProcState = procState;
16905                            app.adjTarget = s.name;
16906                        }
16907                    }
16908                }
16909            }
16910        }
16911
16912        for (int provi = app.pubProviders.size()-1;
16913                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16914                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16915                        || procState > ActivityManager.PROCESS_STATE_TOP);
16916                provi--) {
16917            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16918            for (int i = cpr.connections.size()-1;
16919                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16920                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16921                            || procState > ActivityManager.PROCESS_STATE_TOP);
16922                    i--) {
16923                ContentProviderConnection conn = cpr.connections.get(i);
16924                ProcessRecord client = conn.client;
16925                if (client == app) {
16926                    // Being our own client is not interesting.
16927                    continue;
16928                }
16929                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16930                int clientProcState = client.curProcState;
16931                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16932                    // If the other app is cached for any reason, for purposes here
16933                    // we are going to consider it empty.
16934                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16935                }
16936                if (adj > clientAdj) {
16937                    if (app.hasShownUi && app != mHomeProcess
16938                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16939                        app.adjType = "cch-ui-provider";
16940                    } else {
16941                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16942                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16943                        app.adjType = "provider";
16944                    }
16945                    app.cached &= client.cached;
16946                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16947                            .REASON_PROVIDER_IN_USE;
16948                    app.adjSource = client;
16949                    app.adjSourceProcState = clientProcState;
16950                    app.adjTarget = cpr.name;
16951                }
16952                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16953                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16954                        // Special handling of clients who are in the top state.
16955                        // We *may* want to consider this process to be in the
16956                        // top state as well, but only if there is not another
16957                        // reason for it to be running.  Being on the top is a
16958                        // special state, meaning you are specifically running
16959                        // for the current top app.  If the process is already
16960                        // running in the background for some other reason, it
16961                        // is more important to continue considering it to be
16962                        // in the background state.
16963                        mayBeTop = true;
16964                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16965                    } else {
16966                        // Special handling for above-top states (persistent
16967                        // processes).  These should not bring the current process
16968                        // into the top state, since they are not on top.  Instead
16969                        // give them the best state after that.
16970                        clientProcState =
16971                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16972                    }
16973                }
16974                if (procState > clientProcState) {
16975                    procState = clientProcState;
16976                }
16977                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16978                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16979                }
16980            }
16981            // If the provider has external (non-framework) process
16982            // dependencies, ensure that its adjustment is at least
16983            // FOREGROUND_APP_ADJ.
16984            if (cpr.hasExternalProcessHandles()) {
16985                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16986                    adj = ProcessList.FOREGROUND_APP_ADJ;
16987                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16988                    app.cached = false;
16989                    app.adjType = "provider";
16990                    app.adjTarget = cpr.name;
16991                }
16992                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16993                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16994                }
16995            }
16996        }
16997
16998        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16999            // A client of one of our services or providers is in the top state.  We
17000            // *may* want to be in the top state, but not if we are already running in
17001            // the background for some other reason.  For the decision here, we are going
17002            // to pick out a few specific states that we want to remain in when a client
17003            // is top (states that tend to be longer-term) and otherwise allow it to go
17004            // to the top state.
17005            switch (procState) {
17006                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17007                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17008                case ActivityManager.PROCESS_STATE_SERVICE:
17009                    // These all are longer-term states, so pull them up to the top
17010                    // of the background states, but not all the way to the top state.
17011                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17012                    break;
17013                default:
17014                    // Otherwise, top is a better choice, so take it.
17015                    procState = ActivityManager.PROCESS_STATE_TOP;
17016                    break;
17017            }
17018        }
17019
17020        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17021            if (app.hasClientActivities) {
17022                // This is a cached process, but with client activities.  Mark it so.
17023                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17024                app.adjType = "cch-client-act";
17025            } else if (app.treatLikeActivity) {
17026                // This is a cached process, but somebody wants us to treat it like it has
17027                // an activity, okay!
17028                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17029                app.adjType = "cch-as-act";
17030            }
17031        }
17032
17033        if (adj == ProcessList.SERVICE_ADJ) {
17034            if (doingAll) {
17035                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17036                mNewNumServiceProcs++;
17037                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17038                if (!app.serviceb) {
17039                    // This service isn't far enough down on the LRU list to
17040                    // normally be a B service, but if we are low on RAM and it
17041                    // is large we want to force it down since we would prefer to
17042                    // keep launcher over it.
17043                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17044                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17045                        app.serviceHighRam = true;
17046                        app.serviceb = true;
17047                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17048                    } else {
17049                        mNewNumAServiceProcs++;
17050                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17051                    }
17052                } else {
17053                    app.serviceHighRam = false;
17054                }
17055            }
17056            if (app.serviceb) {
17057                adj = ProcessList.SERVICE_B_ADJ;
17058            }
17059        }
17060
17061        app.curRawAdj = adj;
17062
17063        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17064        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17065        if (adj > app.maxAdj) {
17066            adj = app.maxAdj;
17067            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17068                schedGroup = Process.THREAD_GROUP_DEFAULT;
17069            }
17070        }
17071
17072        // Do final modification to adj.  Everything we do between here and applying
17073        // the final setAdj must be done in this function, because we will also use
17074        // it when computing the final cached adj later.  Note that we don't need to
17075        // worry about this for max adj above, since max adj will always be used to
17076        // keep it out of the cached vaues.
17077        app.curAdj = app.modifyRawOomAdj(adj);
17078        app.curSchedGroup = schedGroup;
17079        app.curProcState = procState;
17080        app.foregroundActivities = foregroundActivities;
17081
17082        return app.curRawAdj;
17083    }
17084
17085    /**
17086     * Schedule PSS collection of a process.
17087     */
17088    void requestPssLocked(ProcessRecord proc, int procState) {
17089        if (mPendingPssProcesses.contains(proc)) {
17090            return;
17091        }
17092        if (mPendingPssProcesses.size() == 0) {
17093            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17094        }
17095        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17096        proc.pssProcState = procState;
17097        mPendingPssProcesses.add(proc);
17098    }
17099
17100    /**
17101     * Schedule PSS collection of all processes.
17102     */
17103    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17104        if (!always) {
17105            if (now < (mLastFullPssTime +
17106                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17107                return;
17108            }
17109        }
17110        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17111        mLastFullPssTime = now;
17112        mFullPssPending = true;
17113        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17114        mPendingPssProcesses.clear();
17115        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17116            ProcessRecord app = mLruProcesses.get(i);
17117            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17118                app.pssProcState = app.setProcState;
17119                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17120                        isSleeping(), now);
17121                mPendingPssProcesses.add(app);
17122            }
17123        }
17124        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17125    }
17126
17127    /**
17128     * Ask a given process to GC right now.
17129     */
17130    final void performAppGcLocked(ProcessRecord app) {
17131        try {
17132            app.lastRequestedGc = SystemClock.uptimeMillis();
17133            if (app.thread != null) {
17134                if (app.reportLowMemory) {
17135                    app.reportLowMemory = false;
17136                    app.thread.scheduleLowMemory();
17137                } else {
17138                    app.thread.processInBackground();
17139                }
17140            }
17141        } catch (Exception e) {
17142            // whatever.
17143        }
17144    }
17145
17146    /**
17147     * Returns true if things are idle enough to perform GCs.
17148     */
17149    private final boolean canGcNowLocked() {
17150        boolean processingBroadcasts = false;
17151        for (BroadcastQueue q : mBroadcastQueues) {
17152            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17153                processingBroadcasts = true;
17154            }
17155        }
17156        return !processingBroadcasts
17157                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17158    }
17159
17160    /**
17161     * Perform GCs on all processes that are waiting for it, but only
17162     * if things are idle.
17163     */
17164    final void performAppGcsLocked() {
17165        final int N = mProcessesToGc.size();
17166        if (N <= 0) {
17167            return;
17168        }
17169        if (canGcNowLocked()) {
17170            while (mProcessesToGc.size() > 0) {
17171                ProcessRecord proc = mProcessesToGc.remove(0);
17172                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17173                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17174                            <= SystemClock.uptimeMillis()) {
17175                        // To avoid spamming the system, we will GC processes one
17176                        // at a time, waiting a few seconds between each.
17177                        performAppGcLocked(proc);
17178                        scheduleAppGcsLocked();
17179                        return;
17180                    } else {
17181                        // It hasn't been long enough since we last GCed this
17182                        // process...  put it in the list to wait for its time.
17183                        addProcessToGcListLocked(proc);
17184                        break;
17185                    }
17186                }
17187            }
17188
17189            scheduleAppGcsLocked();
17190        }
17191    }
17192
17193    /**
17194     * If all looks good, perform GCs on all processes waiting for them.
17195     */
17196    final void performAppGcsIfAppropriateLocked() {
17197        if (canGcNowLocked()) {
17198            performAppGcsLocked();
17199            return;
17200        }
17201        // Still not idle, wait some more.
17202        scheduleAppGcsLocked();
17203    }
17204
17205    /**
17206     * Schedule the execution of all pending app GCs.
17207     */
17208    final void scheduleAppGcsLocked() {
17209        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17210
17211        if (mProcessesToGc.size() > 0) {
17212            // Schedule a GC for the time to the next process.
17213            ProcessRecord proc = mProcessesToGc.get(0);
17214            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17215
17216            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17217            long now = SystemClock.uptimeMillis();
17218            if (when < (now+GC_TIMEOUT)) {
17219                when = now + GC_TIMEOUT;
17220            }
17221            mHandler.sendMessageAtTime(msg, when);
17222        }
17223    }
17224
17225    /**
17226     * Add a process to the array of processes waiting to be GCed.  Keeps the
17227     * list in sorted order by the last GC time.  The process can't already be
17228     * on the list.
17229     */
17230    final void addProcessToGcListLocked(ProcessRecord proc) {
17231        boolean added = false;
17232        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17233            if (mProcessesToGc.get(i).lastRequestedGc <
17234                    proc.lastRequestedGc) {
17235                added = true;
17236                mProcessesToGc.add(i+1, proc);
17237                break;
17238            }
17239        }
17240        if (!added) {
17241            mProcessesToGc.add(0, proc);
17242        }
17243    }
17244
17245    /**
17246     * Set up to ask a process to GC itself.  This will either do it
17247     * immediately, or put it on the list of processes to gc the next
17248     * time things are idle.
17249     */
17250    final void scheduleAppGcLocked(ProcessRecord app) {
17251        long now = SystemClock.uptimeMillis();
17252        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17253            return;
17254        }
17255        if (!mProcessesToGc.contains(app)) {
17256            addProcessToGcListLocked(app);
17257            scheduleAppGcsLocked();
17258        }
17259    }
17260
17261    final void checkExcessivePowerUsageLocked(boolean doKills) {
17262        updateCpuStatsNow();
17263
17264        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17265        boolean doWakeKills = doKills;
17266        boolean doCpuKills = doKills;
17267        if (mLastPowerCheckRealtime == 0) {
17268            doWakeKills = false;
17269        }
17270        if (mLastPowerCheckUptime == 0) {
17271            doCpuKills = false;
17272        }
17273        if (stats.isScreenOn()) {
17274            doWakeKills = false;
17275        }
17276        final long curRealtime = SystemClock.elapsedRealtime();
17277        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17278        final long curUptime = SystemClock.uptimeMillis();
17279        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17280        mLastPowerCheckRealtime = curRealtime;
17281        mLastPowerCheckUptime = curUptime;
17282        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17283            doWakeKills = false;
17284        }
17285        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17286            doCpuKills = false;
17287        }
17288        int i = mLruProcesses.size();
17289        while (i > 0) {
17290            i--;
17291            ProcessRecord app = mLruProcesses.get(i);
17292            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17293                long wtime;
17294                synchronized (stats) {
17295                    wtime = stats.getProcessWakeTime(app.info.uid,
17296                            app.pid, curRealtime);
17297                }
17298                long wtimeUsed = wtime - app.lastWakeTime;
17299                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17300                if (DEBUG_POWER) {
17301                    StringBuilder sb = new StringBuilder(128);
17302                    sb.append("Wake for ");
17303                    app.toShortString(sb);
17304                    sb.append(": over ");
17305                    TimeUtils.formatDuration(realtimeSince, sb);
17306                    sb.append(" used ");
17307                    TimeUtils.formatDuration(wtimeUsed, sb);
17308                    sb.append(" (");
17309                    sb.append((wtimeUsed*100)/realtimeSince);
17310                    sb.append("%)");
17311                    Slog.i(TAG, sb.toString());
17312                    sb.setLength(0);
17313                    sb.append("CPU for ");
17314                    app.toShortString(sb);
17315                    sb.append(": over ");
17316                    TimeUtils.formatDuration(uptimeSince, sb);
17317                    sb.append(" used ");
17318                    TimeUtils.formatDuration(cputimeUsed, sb);
17319                    sb.append(" (");
17320                    sb.append((cputimeUsed*100)/uptimeSince);
17321                    sb.append("%)");
17322                    Slog.i(TAG, sb.toString());
17323                }
17324                // If a process has held a wake lock for more
17325                // than 50% of the time during this period,
17326                // that sounds bad.  Kill!
17327                if (doWakeKills && realtimeSince > 0
17328                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17329                    synchronized (stats) {
17330                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17331                                realtimeSince, wtimeUsed);
17332                    }
17333                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17334                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17335                } else if (doCpuKills && uptimeSince > 0
17336                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17337                    synchronized (stats) {
17338                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17339                                uptimeSince, cputimeUsed);
17340                    }
17341                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17342                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17343                } else {
17344                    app.lastWakeTime = wtime;
17345                    app.lastCpuTime = app.curCpuTime;
17346                }
17347            }
17348        }
17349    }
17350
17351    private final boolean applyOomAdjLocked(ProcessRecord app,
17352            ProcessRecord TOP_APP, boolean doingAll, long now) {
17353        boolean success = true;
17354
17355        if (app.curRawAdj != app.setRawAdj) {
17356            app.setRawAdj = app.curRawAdj;
17357        }
17358
17359        int changes = 0;
17360
17361        if (app.curAdj != app.setAdj) {
17362            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17363            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17364                TAG, "Set " + app.pid + " " + app.processName +
17365                " adj " + app.curAdj + ": " + app.adjType);
17366            app.setAdj = app.curAdj;
17367        }
17368
17369        if (app.setSchedGroup != app.curSchedGroup) {
17370            app.setSchedGroup = app.curSchedGroup;
17371            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17372                    "Setting process group of " + app.processName
17373                    + " to " + app.curSchedGroup);
17374            if (app.waitingToKill != null &&
17375                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17376                app.kill(app.waitingToKill, true);
17377                success = false;
17378            } else {
17379                if (true) {
17380                    long oldId = Binder.clearCallingIdentity();
17381                    try {
17382                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17383                    } catch (Exception e) {
17384                        Slog.w(TAG, "Failed setting process group of " + app.pid
17385                                + " to " + app.curSchedGroup);
17386                        e.printStackTrace();
17387                    } finally {
17388                        Binder.restoreCallingIdentity(oldId);
17389                    }
17390                } else {
17391                    if (app.thread != null) {
17392                        try {
17393                            app.thread.setSchedulingGroup(app.curSchedGroup);
17394                        } catch (RemoteException e) {
17395                        }
17396                    }
17397                }
17398                Process.setSwappiness(app.pid,
17399                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17400            }
17401        }
17402        if (app.repForegroundActivities != app.foregroundActivities) {
17403            app.repForegroundActivities = app.foregroundActivities;
17404            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17405        }
17406        if (app.repProcState != app.curProcState) {
17407            app.repProcState = app.curProcState;
17408            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17409            if (app.thread != null) {
17410                try {
17411                    if (false) {
17412                        //RuntimeException h = new RuntimeException("here");
17413                        Slog.i(TAG, "Sending new process state " + app.repProcState
17414                                + " to " + app /*, h*/);
17415                    }
17416                    app.thread.setProcessState(app.repProcState);
17417                } catch (RemoteException e) {
17418                }
17419            }
17420        }
17421        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17422                app.setProcState)) {
17423            app.lastStateTime = now;
17424            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17425                    isSleeping(), now);
17426            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17427                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17428                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17429                    + (app.nextPssTime-now) + ": " + app);
17430        } else {
17431            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17432                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17433                requestPssLocked(app, app.setProcState);
17434                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17435                        isSleeping(), now);
17436            } else if (false && DEBUG_PSS) {
17437                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17438            }
17439        }
17440        if (app.setProcState != app.curProcState) {
17441            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17442                    "Proc state change of " + app.processName
17443                    + " to " + app.curProcState);
17444            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17445            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17446            if (setImportant && !curImportant) {
17447                // This app is no longer something we consider important enough to allow to
17448                // use arbitrary amounts of battery power.  Note
17449                // its current wake lock time to later know to kill it if
17450                // it is not behaving well.
17451                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17452                synchronized (stats) {
17453                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17454                            app.pid, SystemClock.elapsedRealtime());
17455                }
17456                app.lastCpuTime = app.curCpuTime;
17457
17458            }
17459            app.setProcState = app.curProcState;
17460            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17461                app.notCachedSinceIdle = false;
17462            }
17463            if (!doingAll) {
17464                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17465            } else {
17466                app.procStateChanged = true;
17467            }
17468        }
17469
17470        if (changes != 0) {
17471            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17472            int i = mPendingProcessChanges.size()-1;
17473            ProcessChangeItem item = null;
17474            while (i >= 0) {
17475                item = mPendingProcessChanges.get(i);
17476                if (item.pid == app.pid) {
17477                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17478                    break;
17479                }
17480                i--;
17481            }
17482            if (i < 0) {
17483                // No existing item in pending changes; need a new one.
17484                final int NA = mAvailProcessChanges.size();
17485                if (NA > 0) {
17486                    item = mAvailProcessChanges.remove(NA-1);
17487                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17488                } else {
17489                    item = new ProcessChangeItem();
17490                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17491                }
17492                item.changes = 0;
17493                item.pid = app.pid;
17494                item.uid = app.info.uid;
17495                if (mPendingProcessChanges.size() == 0) {
17496                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17497                            "*** Enqueueing dispatch processes changed!");
17498                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17499                }
17500                mPendingProcessChanges.add(item);
17501            }
17502            item.changes |= changes;
17503            item.processState = app.repProcState;
17504            item.foregroundActivities = app.repForegroundActivities;
17505            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17506                    + Integer.toHexString(System.identityHashCode(item))
17507                    + " " + app.toShortString() + ": changes=" + item.changes
17508                    + " procState=" + item.processState
17509                    + " foreground=" + item.foregroundActivities
17510                    + " type=" + app.adjType + " source=" + app.adjSource
17511                    + " target=" + app.adjTarget);
17512        }
17513
17514        return success;
17515    }
17516
17517    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17518        if (proc.thread != null) {
17519            if (proc.baseProcessTracker != null) {
17520                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17521            }
17522            if (proc.repProcState >= 0) {
17523                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17524                        proc.repProcState);
17525            }
17526        }
17527    }
17528
17529    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17530            ProcessRecord TOP_APP, boolean doingAll, long now) {
17531        if (app.thread == null) {
17532            return false;
17533        }
17534
17535        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17536
17537        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17538    }
17539
17540    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17541            boolean oomAdj) {
17542        if (isForeground != proc.foregroundServices) {
17543            proc.foregroundServices = isForeground;
17544            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17545                    proc.info.uid);
17546            if (isForeground) {
17547                if (curProcs == null) {
17548                    curProcs = new ArrayList<ProcessRecord>();
17549                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17550                }
17551                if (!curProcs.contains(proc)) {
17552                    curProcs.add(proc);
17553                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17554                            proc.info.packageName, proc.info.uid);
17555                }
17556            } else {
17557                if (curProcs != null) {
17558                    if (curProcs.remove(proc)) {
17559                        mBatteryStatsService.noteEvent(
17560                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17561                                proc.info.packageName, proc.info.uid);
17562                        if (curProcs.size() <= 0) {
17563                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17564                        }
17565                    }
17566                }
17567            }
17568            if (oomAdj) {
17569                updateOomAdjLocked();
17570            }
17571        }
17572    }
17573
17574    private final ActivityRecord resumedAppLocked() {
17575        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17576        String pkg;
17577        int uid;
17578        if (act != null) {
17579            pkg = act.packageName;
17580            uid = act.info.applicationInfo.uid;
17581        } else {
17582            pkg = null;
17583            uid = -1;
17584        }
17585        // Has the UID or resumed package name changed?
17586        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17587                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17588            if (mCurResumedPackage != null) {
17589                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17590                        mCurResumedPackage, mCurResumedUid);
17591            }
17592            mCurResumedPackage = pkg;
17593            mCurResumedUid = uid;
17594            if (mCurResumedPackage != null) {
17595                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17596                        mCurResumedPackage, mCurResumedUid);
17597            }
17598        }
17599        return act;
17600    }
17601
17602    final boolean updateOomAdjLocked(ProcessRecord app) {
17603        final ActivityRecord TOP_ACT = resumedAppLocked();
17604        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17605        final boolean wasCached = app.cached;
17606
17607        mAdjSeq++;
17608
17609        // This is the desired cached adjusment we want to tell it to use.
17610        // If our app is currently cached, we know it, and that is it.  Otherwise,
17611        // we don't know it yet, and it needs to now be cached we will then
17612        // need to do a complete oom adj.
17613        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17614                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17615        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17616                SystemClock.uptimeMillis());
17617        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17618            // Changed to/from cached state, so apps after it in the LRU
17619            // list may also be changed.
17620            updateOomAdjLocked();
17621        }
17622        return success;
17623    }
17624
17625    final void updateOomAdjLocked() {
17626        final ActivityRecord TOP_ACT = resumedAppLocked();
17627        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17628        final long now = SystemClock.uptimeMillis();
17629        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17630        final int N = mLruProcesses.size();
17631
17632        if (false) {
17633            RuntimeException e = new RuntimeException();
17634            e.fillInStackTrace();
17635            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17636        }
17637
17638        mAdjSeq++;
17639        mNewNumServiceProcs = 0;
17640        mNewNumAServiceProcs = 0;
17641
17642        final int emptyProcessLimit;
17643        final int cachedProcessLimit;
17644        if (mProcessLimit <= 0) {
17645            emptyProcessLimit = cachedProcessLimit = 0;
17646        } else if (mProcessLimit == 1) {
17647            emptyProcessLimit = 1;
17648            cachedProcessLimit = 0;
17649        } else {
17650            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17651            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17652        }
17653
17654        // Let's determine how many processes we have running vs.
17655        // how many slots we have for background processes; we may want
17656        // to put multiple processes in a slot of there are enough of
17657        // them.
17658        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17659                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17660        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17661        if (numEmptyProcs > cachedProcessLimit) {
17662            // If there are more empty processes than our limit on cached
17663            // processes, then use the cached process limit for the factor.
17664            // This ensures that the really old empty processes get pushed
17665            // down to the bottom, so if we are running low on memory we will
17666            // have a better chance at keeping around more cached processes
17667            // instead of a gazillion empty processes.
17668            numEmptyProcs = cachedProcessLimit;
17669        }
17670        int emptyFactor = numEmptyProcs/numSlots;
17671        if (emptyFactor < 1) emptyFactor = 1;
17672        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17673        if (cachedFactor < 1) cachedFactor = 1;
17674        int stepCached = 0;
17675        int stepEmpty = 0;
17676        int numCached = 0;
17677        int numEmpty = 0;
17678        int numTrimming = 0;
17679
17680        mNumNonCachedProcs = 0;
17681        mNumCachedHiddenProcs = 0;
17682
17683        // First update the OOM adjustment for each of the
17684        // application processes based on their current state.
17685        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17686        int nextCachedAdj = curCachedAdj+1;
17687        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17688        int nextEmptyAdj = curEmptyAdj+2;
17689        for (int i=N-1; i>=0; i--) {
17690            ProcessRecord app = mLruProcesses.get(i);
17691            if (!app.killedByAm && app.thread != null) {
17692                app.procStateChanged = false;
17693                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17694
17695                // If we haven't yet assigned the final cached adj
17696                // to the process, do that now.
17697                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17698                    switch (app.curProcState) {
17699                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17700                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17701                            // This process is a cached process holding activities...
17702                            // assign it the next cached value for that type, and then
17703                            // step that cached level.
17704                            app.curRawAdj = curCachedAdj;
17705                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17706                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17707                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17708                                    + ")");
17709                            if (curCachedAdj != nextCachedAdj) {
17710                                stepCached++;
17711                                if (stepCached >= cachedFactor) {
17712                                    stepCached = 0;
17713                                    curCachedAdj = nextCachedAdj;
17714                                    nextCachedAdj += 2;
17715                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17716                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17717                                    }
17718                                }
17719                            }
17720                            break;
17721                        default:
17722                            // For everything else, assign next empty cached process
17723                            // level and bump that up.  Note that this means that
17724                            // long-running services that have dropped down to the
17725                            // cached level will be treated as empty (since their process
17726                            // state is still as a service), which is what we want.
17727                            app.curRawAdj = curEmptyAdj;
17728                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17729                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17730                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17731                                    + ")");
17732                            if (curEmptyAdj != nextEmptyAdj) {
17733                                stepEmpty++;
17734                                if (stepEmpty >= emptyFactor) {
17735                                    stepEmpty = 0;
17736                                    curEmptyAdj = nextEmptyAdj;
17737                                    nextEmptyAdj += 2;
17738                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17739                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17740                                    }
17741                                }
17742                            }
17743                            break;
17744                    }
17745                }
17746
17747                applyOomAdjLocked(app, TOP_APP, true, now);
17748
17749                // Count the number of process types.
17750                switch (app.curProcState) {
17751                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17752                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17753                        mNumCachedHiddenProcs++;
17754                        numCached++;
17755                        if (numCached > cachedProcessLimit) {
17756                            app.kill("cached #" + numCached, true);
17757                        }
17758                        break;
17759                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17760                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17761                                && app.lastActivityTime < oldTime) {
17762                            app.kill("empty for "
17763                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17764                                    / 1000) + "s", true);
17765                        } else {
17766                            numEmpty++;
17767                            if (numEmpty > emptyProcessLimit) {
17768                                app.kill("empty #" + numEmpty, true);
17769                            }
17770                        }
17771                        break;
17772                    default:
17773                        mNumNonCachedProcs++;
17774                        break;
17775                }
17776
17777                if (app.isolated && app.services.size() <= 0) {
17778                    // If this is an isolated process, and there are no
17779                    // services running in it, then the process is no longer
17780                    // needed.  We agressively kill these because we can by
17781                    // definition not re-use the same process again, and it is
17782                    // good to avoid having whatever code was running in them
17783                    // left sitting around after no longer needed.
17784                    app.kill("isolated not needed", true);
17785                }
17786
17787                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17788                        && !app.killedByAm) {
17789                    numTrimming++;
17790                }
17791            }
17792        }
17793
17794        mNumServiceProcs = mNewNumServiceProcs;
17795
17796        // Now determine the memory trimming level of background processes.
17797        // Unfortunately we need to start at the back of the list to do this
17798        // properly.  We only do this if the number of background apps we
17799        // are managing to keep around is less than half the maximum we desire;
17800        // if we are keeping a good number around, we'll let them use whatever
17801        // memory they want.
17802        final int numCachedAndEmpty = numCached + numEmpty;
17803        int memFactor;
17804        if (numCached <= ProcessList.TRIM_CACHED_APPS
17805                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17806            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17807                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17808            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17809                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17810            } else {
17811                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17812            }
17813        } else {
17814            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17815        }
17816        // We always allow the memory level to go up (better).  We only allow it to go
17817        // down if we are in a state where that is allowed, *and* the total number of processes
17818        // has gone down since last time.
17819        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17820                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17821                + " last=" + mLastNumProcesses);
17822        if (memFactor > mLastMemoryLevel) {
17823            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17824                memFactor = mLastMemoryLevel;
17825                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17826            }
17827        }
17828        mLastMemoryLevel = memFactor;
17829        mLastNumProcesses = mLruProcesses.size();
17830        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17831        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17832        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17833            if (mLowRamStartTime == 0) {
17834                mLowRamStartTime = now;
17835            }
17836            int step = 0;
17837            int fgTrimLevel;
17838            switch (memFactor) {
17839                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17840                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17841                    break;
17842                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17843                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17844                    break;
17845                default:
17846                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17847                    break;
17848            }
17849            int factor = numTrimming/3;
17850            int minFactor = 2;
17851            if (mHomeProcess != null) minFactor++;
17852            if (mPreviousProcess != null) minFactor++;
17853            if (factor < minFactor) factor = minFactor;
17854            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17855            for (int i=N-1; i>=0; i--) {
17856                ProcessRecord app = mLruProcesses.get(i);
17857                if (allChanged || app.procStateChanged) {
17858                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17859                    app.procStateChanged = false;
17860                }
17861                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17862                        && !app.killedByAm) {
17863                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17864                        try {
17865                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17866                                    "Trimming memory of " + app.processName
17867                                    + " to " + curLevel);
17868                            app.thread.scheduleTrimMemory(curLevel);
17869                        } catch (RemoteException e) {
17870                        }
17871                        if (false) {
17872                            // For now we won't do this; our memory trimming seems
17873                            // to be good enough at this point that destroying
17874                            // activities causes more harm than good.
17875                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17876                                    && app != mHomeProcess && app != mPreviousProcess) {
17877                                // Need to do this on its own message because the stack may not
17878                                // be in a consistent state at this point.
17879                                // For these apps we will also finish their activities
17880                                // to help them free memory.
17881                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17882                            }
17883                        }
17884                    }
17885                    app.trimMemoryLevel = curLevel;
17886                    step++;
17887                    if (step >= factor) {
17888                        step = 0;
17889                        switch (curLevel) {
17890                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17891                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17892                                break;
17893                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17894                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17895                                break;
17896                        }
17897                    }
17898                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17899                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17900                            && app.thread != null) {
17901                        try {
17902                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17903                                    "Trimming memory of heavy-weight " + app.processName
17904                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17905                            app.thread.scheduleTrimMemory(
17906                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17907                        } catch (RemoteException e) {
17908                        }
17909                    }
17910                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17911                } else {
17912                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17913                            || app.systemNoUi) && app.pendingUiClean) {
17914                        // If this application is now in the background and it
17915                        // had done UI, then give it the special trim level to
17916                        // have it free UI resources.
17917                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17918                        if (app.trimMemoryLevel < level && app.thread != null) {
17919                            try {
17920                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17921                                        "Trimming memory of bg-ui " + app.processName
17922                                        + " to " + level);
17923                                app.thread.scheduleTrimMemory(level);
17924                            } catch (RemoteException e) {
17925                            }
17926                        }
17927                        app.pendingUiClean = false;
17928                    }
17929                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17930                        try {
17931                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17932                                    "Trimming memory of fg " + app.processName
17933                                    + " to " + fgTrimLevel);
17934                            app.thread.scheduleTrimMemory(fgTrimLevel);
17935                        } catch (RemoteException e) {
17936                        }
17937                    }
17938                    app.trimMemoryLevel = fgTrimLevel;
17939                }
17940            }
17941        } else {
17942            if (mLowRamStartTime != 0) {
17943                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17944                mLowRamStartTime = 0;
17945            }
17946            for (int i=N-1; i>=0; i--) {
17947                ProcessRecord app = mLruProcesses.get(i);
17948                if (allChanged || app.procStateChanged) {
17949                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17950                    app.procStateChanged = false;
17951                }
17952                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17953                        || app.systemNoUi) && app.pendingUiClean) {
17954                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17955                            && app.thread != null) {
17956                        try {
17957                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17958                                    "Trimming memory of ui hidden " + app.processName
17959                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17960                            app.thread.scheduleTrimMemory(
17961                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17962                        } catch (RemoteException e) {
17963                        }
17964                    }
17965                    app.pendingUiClean = false;
17966                }
17967                app.trimMemoryLevel = 0;
17968            }
17969        }
17970
17971        if (mAlwaysFinishActivities) {
17972            // Need to do this on its own message because the stack may not
17973            // be in a consistent state at this point.
17974            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17975        }
17976
17977        if (allChanged) {
17978            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17979        }
17980
17981        if (mProcessStats.shouldWriteNowLocked(now)) {
17982            mHandler.post(new Runnable() {
17983                @Override public void run() {
17984                    synchronized (ActivityManagerService.this) {
17985                        mProcessStats.writeStateAsyncLocked();
17986                    }
17987                }
17988            });
17989        }
17990
17991        if (DEBUG_OOM_ADJ) {
17992            if (false) {
17993                RuntimeException here = new RuntimeException("here");
17994                here.fillInStackTrace();
17995                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17996            } else {
17997                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17998            }
17999        }
18000    }
18001
18002    final void trimApplications() {
18003        synchronized (this) {
18004            int i;
18005
18006            // First remove any unused application processes whose package
18007            // has been removed.
18008            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18009                final ProcessRecord app = mRemovedProcesses.get(i);
18010                if (app.activities.size() == 0
18011                        && app.curReceiver == null && app.services.size() == 0) {
18012                    Slog.i(
18013                        TAG, "Exiting empty application process "
18014                        + app.processName + " ("
18015                        + (app.thread != null ? app.thread.asBinder() : null)
18016                        + ")\n");
18017                    if (app.pid > 0 && app.pid != MY_PID) {
18018                        app.kill("empty", false);
18019                    } else {
18020                        try {
18021                            app.thread.scheduleExit();
18022                        } catch (Exception e) {
18023                            // Ignore exceptions.
18024                        }
18025                    }
18026                    cleanUpApplicationRecordLocked(app, false, true, -1);
18027                    mRemovedProcesses.remove(i);
18028
18029                    if (app.persistent) {
18030                        addAppLocked(app.info, false, null /* ABI override */);
18031                    }
18032                }
18033            }
18034
18035            // Now update the oom adj for all processes.
18036            updateOomAdjLocked();
18037        }
18038    }
18039
18040    /** This method sends the specified signal to each of the persistent apps */
18041    public void signalPersistentProcesses(int sig) throws RemoteException {
18042        if (sig != Process.SIGNAL_USR1) {
18043            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18044        }
18045
18046        synchronized (this) {
18047            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18048                    != PackageManager.PERMISSION_GRANTED) {
18049                throw new SecurityException("Requires permission "
18050                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18051            }
18052
18053            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18054                ProcessRecord r = mLruProcesses.get(i);
18055                if (r.thread != null && r.persistent) {
18056                    Process.sendSignal(r.pid, sig);
18057                }
18058            }
18059        }
18060    }
18061
18062    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18063        if (proc == null || proc == mProfileProc) {
18064            proc = mProfileProc;
18065            profileType = mProfileType;
18066            clearProfilerLocked();
18067        }
18068        if (proc == null) {
18069            return;
18070        }
18071        try {
18072            proc.thread.profilerControl(false, null, profileType);
18073        } catch (RemoteException e) {
18074            throw new IllegalStateException("Process disappeared");
18075        }
18076    }
18077
18078    private void clearProfilerLocked() {
18079        if (mProfileFd != null) {
18080            try {
18081                mProfileFd.close();
18082            } catch (IOException e) {
18083            }
18084        }
18085        mProfileApp = null;
18086        mProfileProc = null;
18087        mProfileFile = null;
18088        mProfileType = 0;
18089        mAutoStopProfiler = false;
18090        mSamplingInterval = 0;
18091    }
18092
18093    public boolean profileControl(String process, int userId, boolean start,
18094            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18095
18096        try {
18097            synchronized (this) {
18098                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18099                // its own permission.
18100                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18101                        != PackageManager.PERMISSION_GRANTED) {
18102                    throw new SecurityException("Requires permission "
18103                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18104                }
18105
18106                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18107                    throw new IllegalArgumentException("null profile info or fd");
18108                }
18109
18110                ProcessRecord proc = null;
18111                if (process != null) {
18112                    proc = findProcessLocked(process, userId, "profileControl");
18113                }
18114
18115                if (start && (proc == null || proc.thread == null)) {
18116                    throw new IllegalArgumentException("Unknown process: " + process);
18117                }
18118
18119                if (start) {
18120                    stopProfilerLocked(null, 0);
18121                    setProfileApp(proc.info, proc.processName, profilerInfo);
18122                    mProfileProc = proc;
18123                    mProfileType = profileType;
18124                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18125                    try {
18126                        fd = fd.dup();
18127                    } catch (IOException e) {
18128                        fd = null;
18129                    }
18130                    profilerInfo.profileFd = fd;
18131                    proc.thread.profilerControl(start, profilerInfo, profileType);
18132                    fd = null;
18133                    mProfileFd = null;
18134                } else {
18135                    stopProfilerLocked(proc, profileType);
18136                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18137                        try {
18138                            profilerInfo.profileFd.close();
18139                        } catch (IOException e) {
18140                        }
18141                    }
18142                }
18143
18144                return true;
18145            }
18146        } catch (RemoteException e) {
18147            throw new IllegalStateException("Process disappeared");
18148        } finally {
18149            if (profilerInfo != null && profilerInfo.profileFd != null) {
18150                try {
18151                    profilerInfo.profileFd.close();
18152                } catch (IOException e) {
18153                }
18154            }
18155        }
18156    }
18157
18158    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18159        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18160                userId, true, ALLOW_FULL_ONLY, callName, null);
18161        ProcessRecord proc = null;
18162        try {
18163            int pid = Integer.parseInt(process);
18164            synchronized (mPidsSelfLocked) {
18165                proc = mPidsSelfLocked.get(pid);
18166            }
18167        } catch (NumberFormatException e) {
18168        }
18169
18170        if (proc == null) {
18171            ArrayMap<String, SparseArray<ProcessRecord>> all
18172                    = mProcessNames.getMap();
18173            SparseArray<ProcessRecord> procs = all.get(process);
18174            if (procs != null && procs.size() > 0) {
18175                proc = procs.valueAt(0);
18176                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18177                    for (int i=1; i<procs.size(); i++) {
18178                        ProcessRecord thisProc = procs.valueAt(i);
18179                        if (thisProc.userId == userId) {
18180                            proc = thisProc;
18181                            break;
18182                        }
18183                    }
18184                }
18185            }
18186        }
18187
18188        return proc;
18189    }
18190
18191    public boolean dumpHeap(String process, int userId, boolean managed,
18192            String path, ParcelFileDescriptor fd) throws RemoteException {
18193
18194        try {
18195            synchronized (this) {
18196                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18197                // its own permission (same as profileControl).
18198                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18199                        != PackageManager.PERMISSION_GRANTED) {
18200                    throw new SecurityException("Requires permission "
18201                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18202                }
18203
18204                if (fd == null) {
18205                    throw new IllegalArgumentException("null fd");
18206                }
18207
18208                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18209                if (proc == null || proc.thread == null) {
18210                    throw new IllegalArgumentException("Unknown process: " + process);
18211                }
18212
18213                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18214                if (!isDebuggable) {
18215                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18216                        throw new SecurityException("Process not debuggable: " + proc);
18217                    }
18218                }
18219
18220                proc.thread.dumpHeap(managed, path, fd);
18221                fd = null;
18222                return true;
18223            }
18224        } catch (RemoteException e) {
18225            throw new IllegalStateException("Process disappeared");
18226        } finally {
18227            if (fd != null) {
18228                try {
18229                    fd.close();
18230                } catch (IOException e) {
18231                }
18232            }
18233        }
18234    }
18235
18236    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18237    public void monitor() {
18238        synchronized (this) { }
18239    }
18240
18241    void onCoreSettingsChange(Bundle settings) {
18242        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18243            ProcessRecord processRecord = mLruProcesses.get(i);
18244            try {
18245                if (processRecord.thread != null) {
18246                    processRecord.thread.setCoreSettings(settings);
18247                }
18248            } catch (RemoteException re) {
18249                /* ignore */
18250            }
18251        }
18252    }
18253
18254    // Multi-user methods
18255
18256    /**
18257     * Start user, if its not already running, but don't bring it to foreground.
18258     */
18259    @Override
18260    public boolean startUserInBackground(final int userId) {
18261        return startUser(userId, /* foreground */ false);
18262    }
18263
18264    /**
18265     * Start user, if its not already running, and bring it to foreground.
18266     */
18267    boolean startUserInForeground(final int userId, Dialog dlg) {
18268        boolean result = startUser(userId, /* foreground */ true);
18269        dlg.dismiss();
18270        return result;
18271    }
18272
18273    /**
18274     * Refreshes the list of users related to the current user when either a
18275     * user switch happens or when a new related user is started in the
18276     * background.
18277     */
18278    private void updateCurrentProfileIdsLocked() {
18279        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18280                mCurrentUserId, false /* enabledOnly */);
18281        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18282        for (int i = 0; i < currentProfileIds.length; i++) {
18283            currentProfileIds[i] = profiles.get(i).id;
18284        }
18285        mCurrentProfileIds = currentProfileIds;
18286
18287        synchronized (mUserProfileGroupIdsSelfLocked) {
18288            mUserProfileGroupIdsSelfLocked.clear();
18289            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18290            for (int i = 0; i < users.size(); i++) {
18291                UserInfo user = users.get(i);
18292                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18293                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18294                }
18295            }
18296        }
18297    }
18298
18299    private Set getProfileIdsLocked(int userId) {
18300        Set userIds = new HashSet<Integer>();
18301        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18302                userId, false /* enabledOnly */);
18303        for (UserInfo user : profiles) {
18304            userIds.add(Integer.valueOf(user.id));
18305        }
18306        return userIds;
18307    }
18308
18309    @Override
18310    public boolean switchUser(final int userId) {
18311        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18312        String userName;
18313        synchronized (this) {
18314            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18315            if (userInfo == null) {
18316                Slog.w(TAG, "No user info for user #" + userId);
18317                return false;
18318            }
18319            if (userInfo.isManagedProfile()) {
18320                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18321                return false;
18322            }
18323            userName = userInfo.name;
18324            mTargetUserId = userId;
18325        }
18326        mHandler.removeMessages(START_USER_SWITCH_MSG);
18327        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18328        return true;
18329    }
18330
18331    private void showUserSwitchDialog(int userId, String userName) {
18332        // The dialog will show and then initiate the user switch by calling startUserInForeground
18333        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18334                true /* above system */);
18335        d.show();
18336    }
18337
18338    private boolean startUser(final int userId, final boolean foreground) {
18339        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18340                != PackageManager.PERMISSION_GRANTED) {
18341            String msg = "Permission Denial: switchUser() from pid="
18342                    + Binder.getCallingPid()
18343                    + ", uid=" + Binder.getCallingUid()
18344                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18345            Slog.w(TAG, msg);
18346            throw new SecurityException(msg);
18347        }
18348
18349        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18350
18351        final long ident = Binder.clearCallingIdentity();
18352        try {
18353            synchronized (this) {
18354                final int oldUserId = mCurrentUserId;
18355                if (oldUserId == userId) {
18356                    return true;
18357                }
18358
18359                mStackSupervisor.setLockTaskModeLocked(null, false);
18360
18361                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18362                if (userInfo == null) {
18363                    Slog.w(TAG, "No user info for user #" + userId);
18364                    return false;
18365                }
18366                if (foreground && userInfo.isManagedProfile()) {
18367                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18368                    return false;
18369                }
18370
18371                if (foreground) {
18372                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18373                            R.anim.screen_user_enter);
18374                }
18375
18376                boolean needStart = false;
18377
18378                // If the user we are switching to is not currently started, then
18379                // we need to start it now.
18380                if (mStartedUsers.get(userId) == null) {
18381                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18382                    updateStartedUserArrayLocked();
18383                    needStart = true;
18384                }
18385
18386                final Integer userIdInt = Integer.valueOf(userId);
18387                mUserLru.remove(userIdInt);
18388                mUserLru.add(userIdInt);
18389
18390                if (foreground) {
18391                    mCurrentUserId = userId;
18392                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18393                    updateCurrentProfileIdsLocked();
18394                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18395                    // Once the internal notion of the active user has switched, we lock the device
18396                    // with the option to show the user switcher on the keyguard.
18397                    mWindowManager.lockNow(null);
18398                } else {
18399                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18400                    updateCurrentProfileIdsLocked();
18401                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18402                    mUserLru.remove(currentUserIdInt);
18403                    mUserLru.add(currentUserIdInt);
18404                }
18405
18406                final UserStartedState uss = mStartedUsers.get(userId);
18407
18408                // Make sure user is in the started state.  If it is currently
18409                // stopping, we need to knock that off.
18410                if (uss.mState == UserStartedState.STATE_STOPPING) {
18411                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18412                    // so we can just fairly silently bring the user back from
18413                    // the almost-dead.
18414                    uss.mState = UserStartedState.STATE_RUNNING;
18415                    updateStartedUserArrayLocked();
18416                    needStart = true;
18417                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18418                    // This means ACTION_SHUTDOWN has been sent, so we will
18419                    // need to treat this as a new boot of the user.
18420                    uss.mState = UserStartedState.STATE_BOOTING;
18421                    updateStartedUserArrayLocked();
18422                    needStart = true;
18423                }
18424
18425                if (uss.mState == UserStartedState.STATE_BOOTING) {
18426                    // Booting up a new user, need to tell system services about it.
18427                    // Note that this is on the same handler as scheduling of broadcasts,
18428                    // which is important because it needs to go first.
18429                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18430                }
18431
18432                if (foreground) {
18433                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18434                            oldUserId));
18435                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18436                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18437                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18438                            oldUserId, userId, uss));
18439                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18440                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18441                }
18442
18443                if (needStart) {
18444                    // Send USER_STARTED broadcast
18445                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18446                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18447                            | Intent.FLAG_RECEIVER_FOREGROUND);
18448                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18449                    broadcastIntentLocked(null, null, intent,
18450                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18451                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18452                }
18453
18454                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18455                    if (userId != UserHandle.USER_OWNER) {
18456                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18457                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18458                        broadcastIntentLocked(null, null, intent, null,
18459                                new IIntentReceiver.Stub() {
18460                                    public void performReceive(Intent intent, int resultCode,
18461                                            String data, Bundle extras, boolean ordered,
18462                                            boolean sticky, int sendingUser) {
18463                                        onUserInitialized(uss, foreground, oldUserId, userId);
18464                                    }
18465                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18466                                true, false, MY_PID, Process.SYSTEM_UID,
18467                                userId);
18468                        uss.initializing = true;
18469                    } else {
18470                        getUserManagerLocked().makeInitialized(userInfo.id);
18471                    }
18472                }
18473
18474                if (foreground) {
18475                    if (!uss.initializing) {
18476                        moveUserToForeground(uss, oldUserId, userId);
18477                    }
18478                } else {
18479                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18480                }
18481
18482                if (needStart) {
18483                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18484                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18485                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18486                    broadcastIntentLocked(null, null, intent,
18487                            null, new IIntentReceiver.Stub() {
18488                                @Override
18489                                public void performReceive(Intent intent, int resultCode, String data,
18490                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18491                                        throws RemoteException {
18492                                }
18493                            }, 0, null, null,
18494                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18495                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18496                }
18497            }
18498        } finally {
18499            Binder.restoreCallingIdentity(ident);
18500        }
18501
18502        return true;
18503    }
18504
18505    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18506        long ident = Binder.clearCallingIdentity();
18507        try {
18508            Intent intent;
18509            if (oldUserId >= 0) {
18510                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18511                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18512                int count = profiles.size();
18513                for (int i = 0; i < count; i++) {
18514                    int profileUserId = profiles.get(i).id;
18515                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18516                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18517                            | Intent.FLAG_RECEIVER_FOREGROUND);
18518                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18519                    broadcastIntentLocked(null, null, intent,
18520                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18521                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18522                }
18523            }
18524            if (newUserId >= 0) {
18525                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18526                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18527                int count = profiles.size();
18528                for (int i = 0; i < count; i++) {
18529                    int profileUserId = profiles.get(i).id;
18530                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18531                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18532                            | Intent.FLAG_RECEIVER_FOREGROUND);
18533                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18534                    broadcastIntentLocked(null, null, intent,
18535                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18536                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18537                }
18538                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18539                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18540                        | Intent.FLAG_RECEIVER_FOREGROUND);
18541                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18542                broadcastIntentLocked(null, null, intent,
18543                        null, null, 0, null, null,
18544                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18545                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18546            }
18547        } finally {
18548            Binder.restoreCallingIdentity(ident);
18549        }
18550    }
18551
18552    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18553            final int newUserId) {
18554        final int N = mUserSwitchObservers.beginBroadcast();
18555        if (N > 0) {
18556            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18557                int mCount = 0;
18558                @Override
18559                public void sendResult(Bundle data) throws RemoteException {
18560                    synchronized (ActivityManagerService.this) {
18561                        if (mCurUserSwitchCallback == this) {
18562                            mCount++;
18563                            if (mCount == N) {
18564                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18565                            }
18566                        }
18567                    }
18568                }
18569            };
18570            synchronized (this) {
18571                uss.switching = true;
18572                mCurUserSwitchCallback = callback;
18573            }
18574            for (int i=0; i<N; i++) {
18575                try {
18576                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18577                            newUserId, callback);
18578                } catch (RemoteException e) {
18579                }
18580            }
18581        } else {
18582            synchronized (this) {
18583                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18584            }
18585        }
18586        mUserSwitchObservers.finishBroadcast();
18587    }
18588
18589    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18590        synchronized (this) {
18591            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18592            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18593        }
18594    }
18595
18596    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18597        mCurUserSwitchCallback = null;
18598        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18599        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18600                oldUserId, newUserId, uss));
18601    }
18602
18603    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18604        synchronized (this) {
18605            if (foreground) {
18606                moveUserToForeground(uss, oldUserId, newUserId);
18607            }
18608        }
18609
18610        completeSwitchAndInitalize(uss, newUserId, true, false);
18611    }
18612
18613    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18614        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18615        if (homeInFront) {
18616            startHomeActivityLocked(newUserId);
18617        } else {
18618            mStackSupervisor.resumeTopActivitiesLocked();
18619        }
18620        EventLogTags.writeAmSwitchUser(newUserId);
18621        getUserManagerLocked().userForeground(newUserId);
18622        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18623    }
18624
18625    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18626        completeSwitchAndInitalize(uss, newUserId, false, true);
18627    }
18628
18629    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18630            boolean clearInitializing, boolean clearSwitching) {
18631        boolean unfrozen = false;
18632        synchronized (this) {
18633            if (clearInitializing) {
18634                uss.initializing = false;
18635                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18636            }
18637            if (clearSwitching) {
18638                uss.switching = false;
18639            }
18640            if (!uss.switching && !uss.initializing) {
18641                mWindowManager.stopFreezingScreen();
18642                unfrozen = true;
18643            }
18644        }
18645        if (unfrozen) {
18646            final int N = mUserSwitchObservers.beginBroadcast();
18647            for (int i=0; i<N; i++) {
18648                try {
18649                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18650                } catch (RemoteException e) {
18651                }
18652            }
18653            mUserSwitchObservers.finishBroadcast();
18654        }
18655    }
18656
18657    void scheduleStartProfilesLocked() {
18658        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18659            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18660                    DateUtils.SECOND_IN_MILLIS);
18661        }
18662    }
18663
18664    void startProfilesLocked() {
18665        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18666        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18667                mCurrentUserId, false /* enabledOnly */);
18668        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18669        for (UserInfo user : profiles) {
18670            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18671                    && user.id != mCurrentUserId) {
18672                toStart.add(user);
18673            }
18674        }
18675        final int n = toStart.size();
18676        int i = 0;
18677        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18678            startUserInBackground(toStart.get(i).id);
18679        }
18680        if (i < n) {
18681            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18682        }
18683    }
18684
18685    void finishUserBoot(UserStartedState uss) {
18686        synchronized (this) {
18687            if (uss.mState == UserStartedState.STATE_BOOTING
18688                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18689                uss.mState = UserStartedState.STATE_RUNNING;
18690                final int userId = uss.mHandle.getIdentifier();
18691                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18692                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18693                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18694                broadcastIntentLocked(null, null, intent,
18695                        null, null, 0, null, null,
18696                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18697                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18698            }
18699        }
18700    }
18701
18702    void finishUserSwitch(UserStartedState uss) {
18703        synchronized (this) {
18704            finishUserBoot(uss);
18705
18706            startProfilesLocked();
18707
18708            int num = mUserLru.size();
18709            int i = 0;
18710            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18711                Integer oldUserId = mUserLru.get(i);
18712                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18713                if (oldUss == null) {
18714                    // Shouldn't happen, but be sane if it does.
18715                    mUserLru.remove(i);
18716                    num--;
18717                    continue;
18718                }
18719                if (oldUss.mState == UserStartedState.STATE_STOPPING
18720                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18721                    // This user is already stopping, doesn't count.
18722                    num--;
18723                    i++;
18724                    continue;
18725                }
18726                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18727                    // Owner and current can't be stopped, but count as running.
18728                    i++;
18729                    continue;
18730                }
18731                // This is a user to be stopped.
18732                stopUserLocked(oldUserId, null);
18733                num--;
18734                i++;
18735            }
18736        }
18737    }
18738
18739    @Override
18740    public int stopUser(final int userId, final IStopUserCallback callback) {
18741        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18742                != PackageManager.PERMISSION_GRANTED) {
18743            String msg = "Permission Denial: switchUser() from pid="
18744                    + Binder.getCallingPid()
18745                    + ", uid=" + Binder.getCallingUid()
18746                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18747            Slog.w(TAG, msg);
18748            throw new SecurityException(msg);
18749        }
18750        if (userId <= 0) {
18751            throw new IllegalArgumentException("Can't stop primary user " + userId);
18752        }
18753        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18754        synchronized (this) {
18755            return stopUserLocked(userId, callback);
18756        }
18757    }
18758
18759    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18760        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18761        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18762            return ActivityManager.USER_OP_IS_CURRENT;
18763        }
18764
18765        final UserStartedState uss = mStartedUsers.get(userId);
18766        if (uss == null) {
18767            // User is not started, nothing to do...  but we do need to
18768            // callback if requested.
18769            if (callback != null) {
18770                mHandler.post(new Runnable() {
18771                    @Override
18772                    public void run() {
18773                        try {
18774                            callback.userStopped(userId);
18775                        } catch (RemoteException e) {
18776                        }
18777                    }
18778                });
18779            }
18780            return ActivityManager.USER_OP_SUCCESS;
18781        }
18782
18783        if (callback != null) {
18784            uss.mStopCallbacks.add(callback);
18785        }
18786
18787        if (uss.mState != UserStartedState.STATE_STOPPING
18788                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18789            uss.mState = UserStartedState.STATE_STOPPING;
18790            updateStartedUserArrayLocked();
18791
18792            long ident = Binder.clearCallingIdentity();
18793            try {
18794                // We are going to broadcast ACTION_USER_STOPPING and then
18795                // once that is done send a final ACTION_SHUTDOWN and then
18796                // stop the user.
18797                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18798                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18799                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18800                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18801                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18802                // This is the result receiver for the final shutdown broadcast.
18803                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18804                    @Override
18805                    public void performReceive(Intent intent, int resultCode, String data,
18806                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18807                        finishUserStop(uss);
18808                    }
18809                };
18810                // This is the result receiver for the initial stopping broadcast.
18811                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18812                    @Override
18813                    public void performReceive(Intent intent, int resultCode, String data,
18814                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18815                        // On to the next.
18816                        synchronized (ActivityManagerService.this) {
18817                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18818                                // Whoops, we are being started back up.  Abort, abort!
18819                                return;
18820                            }
18821                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18822                        }
18823                        mBatteryStatsService.noteEvent(
18824                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18825                                Integer.toString(userId), userId);
18826                        mSystemServiceManager.stopUser(userId);
18827                        broadcastIntentLocked(null, null, shutdownIntent,
18828                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18829                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18830                    }
18831                };
18832                // Kick things off.
18833                broadcastIntentLocked(null, null, stoppingIntent,
18834                        null, stoppingReceiver, 0, null, null,
18835                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18836                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18837            } finally {
18838                Binder.restoreCallingIdentity(ident);
18839            }
18840        }
18841
18842        return ActivityManager.USER_OP_SUCCESS;
18843    }
18844
18845    void finishUserStop(UserStartedState uss) {
18846        final int userId = uss.mHandle.getIdentifier();
18847        boolean stopped;
18848        ArrayList<IStopUserCallback> callbacks;
18849        synchronized (this) {
18850            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18851            if (mStartedUsers.get(userId) != uss) {
18852                stopped = false;
18853            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18854                stopped = false;
18855            } else {
18856                stopped = true;
18857                // User can no longer run.
18858                mStartedUsers.remove(userId);
18859                mUserLru.remove(Integer.valueOf(userId));
18860                updateStartedUserArrayLocked();
18861
18862                // Clean up all state and processes associated with the user.
18863                // Kill all the processes for the user.
18864                forceStopUserLocked(userId, "finish user");
18865            }
18866
18867            // Explicitly remove the old information in mRecentTasks.
18868            removeRecentTasksForUserLocked(userId);
18869        }
18870
18871        for (int i=0; i<callbacks.size(); i++) {
18872            try {
18873                if (stopped) callbacks.get(i).userStopped(userId);
18874                else callbacks.get(i).userStopAborted(userId);
18875            } catch (RemoteException e) {
18876            }
18877        }
18878
18879        if (stopped) {
18880            mSystemServiceManager.cleanupUser(userId);
18881            synchronized (this) {
18882                mStackSupervisor.removeUserLocked(userId);
18883            }
18884        }
18885    }
18886
18887    @Override
18888    public UserInfo getCurrentUser() {
18889        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18890                != PackageManager.PERMISSION_GRANTED) && (
18891                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18892                != PackageManager.PERMISSION_GRANTED)) {
18893            String msg = "Permission Denial: getCurrentUser() from pid="
18894                    + Binder.getCallingPid()
18895                    + ", uid=" + Binder.getCallingUid()
18896                    + " requires " + INTERACT_ACROSS_USERS;
18897            Slog.w(TAG, msg);
18898            throw new SecurityException(msg);
18899        }
18900        synchronized (this) {
18901            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18902            return getUserManagerLocked().getUserInfo(userId);
18903        }
18904    }
18905
18906    int getCurrentUserIdLocked() {
18907        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18908    }
18909
18910    @Override
18911    public boolean isUserRunning(int userId, boolean orStopped) {
18912        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18913                != PackageManager.PERMISSION_GRANTED) {
18914            String msg = "Permission Denial: isUserRunning() from pid="
18915                    + Binder.getCallingPid()
18916                    + ", uid=" + Binder.getCallingUid()
18917                    + " requires " + INTERACT_ACROSS_USERS;
18918            Slog.w(TAG, msg);
18919            throw new SecurityException(msg);
18920        }
18921        synchronized (this) {
18922            return isUserRunningLocked(userId, orStopped);
18923        }
18924    }
18925
18926    boolean isUserRunningLocked(int userId, boolean orStopped) {
18927        UserStartedState state = mStartedUsers.get(userId);
18928        if (state == null) {
18929            return false;
18930        }
18931        if (orStopped) {
18932            return true;
18933        }
18934        return state.mState != UserStartedState.STATE_STOPPING
18935                && state.mState != UserStartedState.STATE_SHUTDOWN;
18936    }
18937
18938    @Override
18939    public int[] getRunningUserIds() {
18940        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18941                != PackageManager.PERMISSION_GRANTED) {
18942            String msg = "Permission Denial: isUserRunning() from pid="
18943                    + Binder.getCallingPid()
18944                    + ", uid=" + Binder.getCallingUid()
18945                    + " requires " + INTERACT_ACROSS_USERS;
18946            Slog.w(TAG, msg);
18947            throw new SecurityException(msg);
18948        }
18949        synchronized (this) {
18950            return mStartedUserArray;
18951        }
18952    }
18953
18954    private void updateStartedUserArrayLocked() {
18955        int num = 0;
18956        for (int i=0; i<mStartedUsers.size();  i++) {
18957            UserStartedState uss = mStartedUsers.valueAt(i);
18958            // This list does not include stopping users.
18959            if (uss.mState != UserStartedState.STATE_STOPPING
18960                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18961                num++;
18962            }
18963        }
18964        mStartedUserArray = new int[num];
18965        num = 0;
18966        for (int i=0; i<mStartedUsers.size();  i++) {
18967            UserStartedState uss = mStartedUsers.valueAt(i);
18968            if (uss.mState != UserStartedState.STATE_STOPPING
18969                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18970                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18971                num++;
18972            }
18973        }
18974    }
18975
18976    @Override
18977    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18978        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18979                != PackageManager.PERMISSION_GRANTED) {
18980            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18981                    + Binder.getCallingPid()
18982                    + ", uid=" + Binder.getCallingUid()
18983                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18984            Slog.w(TAG, msg);
18985            throw new SecurityException(msg);
18986        }
18987
18988        mUserSwitchObservers.register(observer);
18989    }
18990
18991    @Override
18992    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18993        mUserSwitchObservers.unregister(observer);
18994    }
18995
18996    private boolean userExists(int userId) {
18997        if (userId == 0) {
18998            return true;
18999        }
19000        UserManagerService ums = getUserManagerLocked();
19001        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19002    }
19003
19004    int[] getUsersLocked() {
19005        UserManagerService ums = getUserManagerLocked();
19006        return ums != null ? ums.getUserIds() : new int[] { 0 };
19007    }
19008
19009    UserManagerService getUserManagerLocked() {
19010        if (mUserManager == null) {
19011            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19012            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19013        }
19014        return mUserManager;
19015    }
19016
19017    private int applyUserId(int uid, int userId) {
19018        return UserHandle.getUid(userId, uid);
19019    }
19020
19021    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19022        if (info == null) return null;
19023        ApplicationInfo newInfo = new ApplicationInfo(info);
19024        newInfo.uid = applyUserId(info.uid, userId);
19025        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19026                + info.packageName;
19027        return newInfo;
19028    }
19029
19030    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19031        if (aInfo == null
19032                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19033            return aInfo;
19034        }
19035
19036        ActivityInfo info = new ActivityInfo(aInfo);
19037        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19038        return info;
19039    }
19040
19041    private final class LocalService extends ActivityManagerInternal {
19042        @Override
19043        public void goingToSleep() {
19044            ActivityManagerService.this.goingToSleep();
19045        }
19046
19047        @Override
19048        public void wakingUp() {
19049            ActivityManagerService.this.wakingUp();
19050        }
19051
19052        @Override
19053        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19054                String processName, String abiOverride, int uid, Runnable crashHandler) {
19055            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19056                    processName, abiOverride, uid, crashHandler);
19057        }
19058    }
19059
19060    /**
19061     * An implementation of IAppTask, that allows an app to manage its own tasks via
19062     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19063     * only the process that calls getAppTasks() can call the AppTask methods.
19064     */
19065    class AppTaskImpl extends IAppTask.Stub {
19066        private int mTaskId;
19067        private int mCallingUid;
19068
19069        public AppTaskImpl(int taskId, int callingUid) {
19070            mTaskId = taskId;
19071            mCallingUid = callingUid;
19072        }
19073
19074        private void checkCaller() {
19075            if (mCallingUid != Binder.getCallingUid()) {
19076                throw new SecurityException("Caller " + mCallingUid
19077                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19078            }
19079        }
19080
19081        @Override
19082        public void finishAndRemoveTask() {
19083            checkCaller();
19084
19085            synchronized (ActivityManagerService.this) {
19086                long origId = Binder.clearCallingIdentity();
19087                try {
19088                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19089                    if (tr == null) {
19090                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19091                    }
19092                    // Only kill the process if we are not a new document
19093                    int flags = tr.getBaseIntent().getFlags();
19094                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
19095                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
19096                    removeTaskByIdLocked(mTaskId,
19097                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
19098                } finally {
19099                    Binder.restoreCallingIdentity(origId);
19100                }
19101            }
19102        }
19103
19104        @Override
19105        public ActivityManager.RecentTaskInfo getTaskInfo() {
19106            checkCaller();
19107
19108            synchronized (ActivityManagerService.this) {
19109                long origId = Binder.clearCallingIdentity();
19110                try {
19111                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19112                    if (tr == null) {
19113                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19114                    }
19115                    return createRecentTaskInfoFromTaskRecord(tr);
19116                } finally {
19117                    Binder.restoreCallingIdentity(origId);
19118                }
19119            }
19120        }
19121
19122        @Override
19123        public void moveToFront() {
19124            checkCaller();
19125
19126            final TaskRecord tr;
19127            synchronized (ActivityManagerService.this) {
19128                tr = recentTaskForIdLocked(mTaskId);
19129                if (tr == null) {
19130                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19131                }
19132                if (tr.getRootActivity() != null) {
19133                    moveTaskToFrontLocked(tr.taskId, 0, null);
19134                    return;
19135                }
19136            }
19137
19138            startActivityFromRecentsInner(tr.taskId, null);
19139        }
19140
19141        @Override
19142        public int startActivity(IBinder whoThread, String callingPackage,
19143                Intent intent, String resolvedType, Bundle options) {
19144            checkCaller();
19145
19146            int callingUser = UserHandle.getCallingUserId();
19147            TaskRecord tr;
19148            IApplicationThread appThread;
19149            synchronized (ActivityManagerService.this) {
19150                tr = recentTaskForIdLocked(mTaskId);
19151                if (tr == null) {
19152                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19153                }
19154                appThread = ApplicationThreadNative.asInterface(whoThread);
19155                if (appThread == null) {
19156                    throw new IllegalArgumentException("Bad app thread " + appThread);
19157                }
19158            }
19159            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19160                    resolvedType, null, null, null, null, 0, 0, null, null,
19161                    null, options, callingUser, null, tr);
19162        }
19163
19164        @Override
19165        public void setExcludeFromRecents(boolean exclude) {
19166            checkCaller();
19167
19168            synchronized (ActivityManagerService.this) {
19169                long origId = Binder.clearCallingIdentity();
19170                try {
19171                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19172                    if (tr == null) {
19173                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19174                    }
19175                    Intent intent = tr.getBaseIntent();
19176                    if (exclude) {
19177                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19178                    } else {
19179                        intent.setFlags(intent.getFlags()
19180                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19181                    }
19182                } finally {
19183                    Binder.restoreCallingIdentity(origId);
19184                }
19185            }
19186        }
19187    }
19188}
19189